Advertisement
Guest User

WithCancelationToken example

a guest
Oct 13th, 2016
1,533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.70 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10.  
  11. namespace ConsoleApplication1
  12. {
  13.     class Program
  14.     {
  15.         public static void Main()
  16.         {
  17.             var tokenSource = new CancellationTokenSource();
  18.             var token = tokenSource.Token;
  19.  
  20.             // Store references to the tasks so that we can wait on them and  
  21.             // observe their status after cancellation.
  22.             Console.WriteLine("Press any key to begin tasks...");
  23.             Console.ReadKey(true);
  24.             Console.WriteLine("To terminate the example, press 'c' to cancel and exit...");
  25.             Console.WriteLine();
  26.  
  27.             var tasks = createBeaverTasks(token);
  28.  
  29.             // Request cancellation from the UI thread.
  30.             char ch = Console.ReadKey().KeyChar;
  31.             if (ch == 'c' || ch == 'C')
  32.             {
  33.                 tokenSource.Cancel();
  34.                 Console.WriteLine("\nTask cancellation requested.");
  35.  
  36.                 // Optional: Observe the change in the Status property on the task.
  37.                 // It is not necessary to wait on tasks that have canceled. However,
  38.                 // if you do wait, you must enclose the call in a try-catch block to
  39.                 // catch the TaskCanceledExceptions that are thrown. If you do  
  40.                 // not wait, no exception is thrown if the token that was passed to the  
  41.                 // StartNew method is the same token that requested the cancellation.
  42.             }
  43.  
  44.             try
  45.             {
  46.                 Task.WaitAll(tasks.ToArray());
  47.             }
  48.             catch (AggregateException e)
  49.             {
  50.                 Console.WriteLine("\nAggregateException thrown with the following inner exceptions:");
  51.                 // Display information about each exception.
  52.                 foreach (var v in e.InnerExceptions)
  53.                 {
  54.                     if (v is TaskCanceledException)
  55.                         Console.WriteLine("   TaskCanceledException: Task {0}",
  56.                                           ((TaskCanceledException)v).Task.Id);
  57.                     else
  58.                         Console.WriteLine("   Exception: {0}", v.GetType().Name);
  59.                 }
  60.                 Console.WriteLine();
  61.             }
  62.             finally
  63.             {
  64.                 tokenSource.Dispose();
  65.             }
  66.  
  67.             // Display status of all tasks.
  68.             foreach (var task in tasks)
  69.                 Console.WriteLine("Task {0} status is now {1}", task.Id, task.Status);
  70.         }
  71.  
  72.         private static ConcurrentBag<Task> createBeaverTasks(CancellationToken token)
  73.         {
  74.             ConcurrentBag<Task> tasks = new ConcurrentBag<Task>();
  75.             BusyBeaver beaver = new BusyBeaver();
  76.             Task t = Task.Factory.StartNew(() => beaver.DoWork(), token);
  77.            
  78.             tasks.Add(t.WithCancellation(token, beaver.Abort));
  79.  
  80.             return tasks;
  81.         }
  82.     }
  83.  
  84.     public class BusyBeaver
  85.     {
  86.         private bool _aborted = false;
  87.  
  88.         public string DoWork()
  89.         {
  90.             var sw = new SpinWait();
  91.             int i = 0;
  92.             while (!_aborted && i++ < 100)
  93.             {
  94.                 Thread.SpinWait(1000000);
  95.                 sw.SpinOnce();
  96.                 Console.Out.WriteLine(sw.Count);
  97.             }
  98.             if (_aborted)
  99.                 throw new BeaverAbortedException();
  100.             return "success";
  101.         }
  102.  
  103.         public void Abort()
  104.         {
  105.             _aborted = true;
  106.         }
  107.  
  108.         public class BeaverAbortedException : Exception
  109.         {
  110.            
  111.         }
  112.     }
  113.  
  114.     public static class WebRequestExtension
  115.     {
  116.         public static async Task WithCancellation(this Task task, CancellationToken cancellationToken, Action action, bool useSynchronizationContext = true)
  117.         {
  118.             using (cancellationToken.Register(action, useSynchronizationContext))
  119.             {
  120.                 try
  121.                 {
  122.                     await task;
  123.                 }
  124.                 catch (Exception ex)
  125.                 {
  126.  
  127.                     if (cancellationToken.IsCancellationRequested)
  128.                     {
  129.                         // the WebException will be available as Exception.InnerException
  130.                         throw new OperationCanceledException(ex.Message, ex, cancellationToken);
  131.                     }
  132.  
  133.                     // cancellation hasn't been requested, rethrow the original WebException
  134.                     throw;
  135.                 }
  136.             }
  137.         }
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement