Guest User

Untitled

a guest
Apr 23rd, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.12 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using System.Timers;
  8.  
  9. namespace GWork
  10. {
  11.     public class RequestList
  12.     {
  13.         public event Action<RequestMessage> OnRequestMessageAdded = delegate { };
  14.         public event Action<RequestMessage> OnRequestMessageStarted = delegate { };
  15.         public event Action<RequestMessage, ResponseMessage> OnRequestMessageDone = delegate { };
  16.  
  17.         Dictionary<Guid, RequestMessage> requests;
  18.         public RequestList()
  19.         {
  20.             requests = new Dictionary<Guid, RequestMessage>();
  21.         }
  22.  
  23.         private void requestWorker_OnRequestMessageStarted(RequestMessage request)
  24.         {
  25.             OnRequestMessageStarted(request);
  26.         }
  27.  
  28.         private void requestWorker_OnRequestMessageDone(RequestMessage request, ResponseMessage response)
  29.         {
  30.             OnRequestMessageDone(request, response);
  31.         }
  32.  
  33.         public void Add(RequestMessage request)
  34.         {
  35.             if (request.Timeout <= 0)
  36.                 request.Timeout = Timeout.Infinite;
  37.             request.StartDate = DateTime.Now;
  38.             request.Status = MessageStatus.Pending;
  39.             //Create a cancellation token source, this will be used to cancel a task
  40.             request.RequestCancelToken = new CancellationTokenSource();
  41.             requests.Add(request.MessageID, request);
  42.             OnRequestMessageAdded(request);
  43.  
  44.             RequestWorker requestWorker = new RequestWorker(request);
  45.             //Create and start a task and pass on the cancellation token to it
  46.             try
  47.             {
  48.                 requestWorker.OnRequestMessageStarted += new Action<RequestMessage>(requestWorker_OnRequestMessageStarted);
  49.                 requestWorker.OnRequestMessageDone += new Action<RequestMessage, ResponseMessage>(requestWorker_OnRequestMessageDone);
  50.  
  51.                 var task = Task.Factory.StartNew(() =>
  52.                     //We also pass on the token to the operation for it access the token to check for
  53.                     //cancellation
  54.                 requestWorker.Process(), request.RequestCancelToken.Token
  55.                     //Process(request), request.RequestCancelToken.Token
  56.             );
  57.                 task.Wait(request.RequestCancelToken.Token);
  58.             }
  59.             catch (OperationCanceledException)
  60.             {
  61.             }
  62.             finally
  63.             {
  64.                 requestWorker.Dispose();
  65.                 requestWorker = null;
  66.             }
  67.  
  68.         }
  69.  
  70.         public void Cancel(RequestMessage request)
  71.         {
  72.             var dictRequestValue = requests[request.MessageID];
  73.             dictRequestValue.RequestCancelToken.Cancel();
  74.             dictRequestValue.Status = MessageStatus.Cancelled;
  75.         }
  76.  
  77.     }
  78. }
  79.  
  80.  
  81.  
  82.  
  83. using System;
  84. using System.Collections.Generic;
  85. using System.Linq;
  86. using System.Text;
  87. using System.Threading;
  88. using System.Timers;
  89.  
  90. namespace GWork
  91. {
  92.     public class RequestWorker: IDisposable
  93.     {
  94.         RequestMessage request;
  95.         System.Timers.Timer timerTimeout = null;
  96.         public event Action<RequestMessage> OnRequestMessageStarted = delegate { };
  97.         public event Action<RequestMessage, ResponseMessage> OnRequestMessageDone = delegate { };
  98.  
  99.         public RequestWorker(RequestMessage request)
  100.         {
  101.             this.request = request;
  102.         }
  103.  
  104.         public void Dispose()
  105.         {
  106.             if (timerTimeout != null)
  107.             {
  108.                 timerTimeout.Dispose();
  109.                 timerTimeout = null;
  110.                 GC.SuppressFinalize(timerTimeout);
  111.             }
  112.         }
  113.  
  114.         private void ProcessLogin(CancellationToken token)
  115.         {
  116.             //This simulates work
  117.             var sw = new SpinWait();
  118.             for (var i = 0; i < 1000; i++)
  119.             {
  120.                 for (int j = 0; j < 50; j++)
  121.                 {
  122.                     sw.SpinOnce();
  123.                 }
  124.                 //This throws an OperationCanceledException if the token has had cancellation requested
  125.                 token.ThrowIfCancellationRequested();
  126.             }
  127.         }
  128.  
  129.         private ResponseMessage ProcessRequest(CancellationToken token)
  130.         {
  131.             ResponseMessage response = new ResponseMessage(request);
  132.             try
  133.             {
  134.                 //Check for requested cancellation before processing message
  135.                 token.ThrowIfCancellationRequested();
  136.  
  137.                 switch (request.MessageType)
  138.                 {
  139.                     case RequestMessageType.Login:
  140.                         ProcessLogin(token);
  141.                         break;
  142.  
  143.                 }
  144.                 response.Status = MessageStatus.Done;
  145.             }
  146.             catch (OperationCanceledException)
  147.             {
  148.                 response.Status = MessageStatus.Cancelled;
  149.             }
  150.             catch (Exception ex)
  151.             {
  152.                 response.Status = MessageStatus.Error;
  153.                 response.MessageData = String.Format("Error: {0}.  Trace{1}.", ex.Message, ex.StackTrace);
  154.             }
  155.             return response;
  156.         }
  157.  
  158.         //This method contains the operation being executed by the task in parallel
  159.         public void Process()
  160.         {
  161.             request.Status = MessageStatus.Processing;
  162.             OnRequestMessageStarted(request);
  163.             CancellationToken token = request.RequestCancelToken.Token;
  164.  
  165.             timerTimeout = new System.Timers.Timer(request.Timeout);
  166.             timerTimeout.AutoReset = false;
  167.             timerTimeout.Elapsed += new ElapsedEventHandler((s, e) =>
  168.             {
  169.                 if (request.Status != MessageStatus.Cancelled)
  170.                     request.RequestCancelToken.Cancel();
  171.             });
  172.             timerTimeout.Start();
  173.  
  174.             ResponseMessage response = ProcessRequest(token);
  175.  
  176.  
  177.             //This code is reached if the task gets to complete prior to a cancellation request
  178.             request.Status = MessageStatus.Done;
  179.             OnRequestMessageDone(request, response);
  180.         }
  181.  
  182.     }
  183. }
Add Comment
Please, Sign In to add comment