Advertisement
Guest User

Untitled

a guest
Dec 17th, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.12 KB | None | 0 0
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace WorkflowTests
  9. {
  10.     class Program
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             Magic magic = new Magic();
  15.             magic.GenerateQueue(100);
  16.  
  17.             magic.Work(8).Wait(10000);
  18.             magic.Cancel();
  19.  
  20.             Console.ReadLine();
  21.         }
  22.     }
  23.  
  24.     class Magic
  25.     {
  26.         CancellationTokenSource tokenSource = new CancellationTokenSource();
  27.         public ConcurrentQueue<Work> workQueue = new ConcurrentQueue<Work>();        
  28.         public List<Task> tasks = new List<Task>();
  29.        
  30.         public void GenerateQueue(int length)
  31.         {
  32.             foreach (int i in Enumerable.Range(0, length))
  33.             {
  34.                 if(i % 2 != 0)
  35.                     workQueue.Enqueue(new Work1() { ExecuteAt = DateTime.Now.AddSeconds(i) });
  36.                 else
  37.                     workQueue.Enqueue(new Work2() { ExecuteAt = DateTime.Now.AddSeconds(i) });
  38.             }
  39.         }
  40.  
  41.         public Task Work(int DOP)
  42.         {
  43.             foreach (int i in Enumerable.Range(1, DOP))
  44.             {
  45.                 // pseudo context per worker
  46.                 string context = ((char)(i + 64)).ToString();
  47.  
  48.                 // create workers and run them
  49.                 tasks.Add(new Worker(context, workQueue, tokenSource.Token).Start());
  50.             }
  51.  
  52.             return Task.WhenAll(tasks).ContinueWith(Completed);
  53.         }
  54.  
  55.         public void Cancel()
  56.         {
  57.             Console.WriteLine("Cancel requested");
  58.             tokenSource.Cancel();
  59.         }
  60.  
  61.         public void Completed(Task completedTask)
  62.         {
  63.             if(completedTask.IsCanceled)
  64.                 Console.WriteLine("Cancelled");
  65.             else
  66.                 Console.WriteLine("Completed");
  67.         }
  68.     }
  69.  
  70.     public class Worker
  71.     {
  72.         string context;
  73.         ConcurrentQueue<Work> workQueue;
  74.         CancellationToken cancelToken;
  75.  
  76.         public Worker(string context, ConcurrentQueue<Work> workQueue, CancellationToken cancelToken)
  77.         {
  78.             this.context = context;
  79.             this.workQueue = workQueue;
  80.             this.cancelToken = cancelToken;
  81.         }
  82.  
  83.         public Task Start()
  84.         {
  85.             Task workerTask = new Task(Work);
  86.             workerTask.Start();
  87.             return workerTask;
  88.         }
  89.        
  90.         private void Work()
  91.         {
  92.             while (workQueue.Any() && !cancelToken.IsCancellationRequested)
  93.             {
  94.                 if (workQueue.TryDequeue(out Work work))
  95.                 {
  96.                     TimeSpan timeLeft = work.ExecuteAt - DateTime.Now;
  97.  
  98.                     // basic load throttling, should be fixed to execution time rather than real time.
  99.                     if (timeLeft > TimeSpan.Zero)
  100.                         Task.Delay(timeLeft, cancelToken).ContinueWith(t => { }).Wait(); // this is strange :/
  101.  
  102.                     if (!cancelToken.IsCancellationRequested)
  103.                         work.Execute(context);
  104.                 }
  105.             }
  106.         }
  107.     }
  108.    
  109.     public abstract class Work
  110.     {
  111.         // when to be executed
  112.         public DateTime ExecuteAt { get; set; }
  113.  
  114.         // what to be executed
  115.         public abstract void Execute(string context);
  116.     }
  117.  
  118.     public class Work1 : Work
  119.     {
  120.         public override void Execute(string context)
  121.         {
  122.             Console.WriteLine($"{context}1, delay: {Math.Round((ExecuteAt - DateTime.Now).TotalMilliseconds)} ms");
  123.  
  124.             var end = DateTime.Now + TimeSpan.FromSeconds(1);
  125.             while (DateTime.Now < end)
  126.                 ;
  127.         }
  128.     }
  129.  
  130.     public class Work2 : Work
  131.     {
  132.         public override void Execute(string context)
  133.         {
  134.             Console.WriteLine($"{context}2, delay: {Math.Round((ExecuteAt - DateTime.Now).TotalMilliseconds)} ms");
  135.  
  136.             var end = DateTime.Now + TimeSpan.FromSeconds(2);
  137.             while (DateTime.Now < end)
  138.                 ;
  139.            
  140.         }
  141.     }
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement