Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Timers;
- namespace GWork
- {
- public class RequestList
- {
- //create an event for notifing when item was added (use empty delegate to avoid checks if OnItemQueued is null)
- public event Action<RequestMessage> OnRequestMessageAdded = delegate { };
- public event Action<RequestMessage> OnRequestMessageStarted = delegate { };
- public event Action<RequestMessage, ResponseMessage> OnRequestMessageDone = delegate { };
- Dictionary<Guid, RequestMessage> requests;
- public RequestList()
- {
- requests = new Dictionary<Guid, RequestMessage>();
- }
- public void Add(RequestMessage request)
- {
- request.Status = MessageStatus.Pending;
- //Create a cancellation token source, this will be used to cancel a task
- request.RequestCancelToken = new CancellationTokenSource();
- requests.Add(request.MessageID, request);
- OnRequestMessageAdded(request);
- //Create and start a task and pass on the cancellation token to it
- var task = Task.Factory.StartNew(() =>
- //We also pass on the token to the operation for it access the token to check for
- //cancellation
- Process(request), request.RequestCancelToken.Token
- );
- }
- public void Cancel(RequestMessage request)
- {
- var dictRequestValue = (from x in requests
- where x.Key == request.MessageID
- select x).First().Value;
- dictRequestValue.RequestCancelToken.Cancel();
- dictRequestValue.Status = MessageStatus.Cancelled;
- }
- private void ProcessLogin(RequestMessage request, CancellationToken token)
- {
- //This simulates work
- var sw = new SpinWait();
- for (var i = 0; i < 1000; i++)
- {
- for (int j = 0; j < 50; j++)
- {
- sw.SpinOnce();
- }
- //Check for requested cancellation amidst execution logic
- if (token.IsCancellationRequested)
- {
- //This throws an OperationCanceledException if the token has had cancellation requested
- token.ThrowIfCancellationRequested();
- }
- }
- }
- private ResponseMessage ProcessRequest(RequestMessage request, CancellationToken token)
- {
- ResponseMessage response = new ResponseMessage(request);
- try
- {
- //Check for requested cancellation before processing message
- if (token.IsCancellationRequested)
- {
- //This throws an OperationCanceledException if the token has had cancellation requested
- token.ThrowIfCancellationRequested();
- }
- switch (request.MessageType)
- {
- case RequestMessageType.Login:
- ProcessLogin(request, token);
- break;
- }
- response.Status = MessageStatus.Done;
- }
- catch (OperationCanceledException)
- {
- response.Status = MessageStatus.Cancelled;
- }
- catch (Exception ex)
- {
- response.Status = MessageStatus.Error;
- response.MessageData = String.Format("Error: {0}. Trace{1}.", ex.Message, ex.StackTrace);
- }
- return response;
- }
- //This method contains the operation being executed by the task in parallel
- private void Process(RequestMessage request)
- {
- request.Status = MessageStatus.Processing;
- CancellationToken token = request.RequestCancelToken.Token;
- System.Timers.Timer timeout = new System.Timers.Timer(request.Timeout);
- timeout.AutoReset = false;
- timeout.Elapsed += new ElapsedEventHandler((s, e) =>
- {
- request.RequestCancelToken.Cancel();
- });
- timeout.Start();
- ResponseMessage response = ProcessRequest(request, token);
- //This code is reached if the task gets to complete prior to a cancellation request
- request.Status = MessageStatus.Done;
- OnRequestMessageDone(request, response);
- }
- }
- }
Add Comment
Please, Sign In to add comment