Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace ConsoleApplication1
- {
- class Program
- {
- public static void Main()
- {
- var tokenSource = new CancellationTokenSource();
- var token = tokenSource.Token;
- // Store references to the tasks so that we can wait on them and
- // observe their status after cancellation.
- Console.WriteLine("Press any key to begin tasks...");
- Console.ReadKey(true);
- Console.WriteLine("To terminate the example, press 'c' to cancel and exit...");
- Console.WriteLine();
- var tasks = createBeaverTasks(token);
- // Request cancellation from the UI thread.
- char ch = Console.ReadKey().KeyChar;
- if (ch == 'c' || ch == 'C')
- {
- tokenSource.Cancel();
- Console.WriteLine("\nTask cancellation requested.");
- // Optional: Observe the change in the Status property on the task.
- // It is not necessary to wait on tasks that have canceled. However,
- // if you do wait, you must enclose the call in a try-catch block to
- // catch the TaskCanceledExceptions that are thrown. If you do
- // not wait, no exception is thrown if the token that was passed to the
- // StartNew method is the same token that requested the cancellation.
- }
- try
- {
- Task.WaitAll(tasks.ToArray());
- }
- catch (AggregateException e)
- {
- Console.WriteLine("\nAggregateException thrown with the following inner exceptions:");
- // Display information about each exception.
- foreach (var v in e.InnerExceptions)
- {
- if (v is TaskCanceledException)
- Console.WriteLine(" TaskCanceledException: Task {0}",
- ((TaskCanceledException)v).Task.Id);
- else
- Console.WriteLine(" Exception: {0}", v.GetType().Name);
- }
- Console.WriteLine();
- }
- finally
- {
- tokenSource.Dispose();
- }
- // Display status of all tasks.
- foreach (var task in tasks)
- Console.WriteLine("Task {0} status is now {1}", task.Id, task.Status);
- }
- private static ConcurrentBag<Task> createBeaverTasks(CancellationToken token)
- {
- ConcurrentBag<Task> tasks = new ConcurrentBag<Task>();
- BusyBeaver beaver = new BusyBeaver();
- Task t = Task.Factory.StartNew(() => beaver.DoWork(), token);
- tasks.Add(t.WithCancellation(token, beaver.Abort));
- return tasks;
- }
- }
- public class BusyBeaver
- {
- private bool _aborted = false;
- public string DoWork()
- {
- var sw = new SpinWait();
- int i = 0;
- while (!_aborted && i++ < 100)
- {
- Thread.SpinWait(1000000);
- sw.SpinOnce();
- Console.Out.WriteLine(sw.Count);
- }
- if (_aborted)
- throw new BeaverAbortedException();
- return "success";
- }
- public void Abort()
- {
- _aborted = true;
- }
- public class BeaverAbortedException : Exception
- {
- }
- }
- public static class WebRequestExtension
- {
- public static async Task WithCancellation(this Task task, CancellationToken cancellationToken, Action action, bool useSynchronizationContext = true)
- {
- using (cancellationToken.Register(action, useSynchronizationContext))
- {
- try
- {
- await task;
- }
- catch (Exception ex)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- // the WebException will be available as Exception.InnerException
- throw new OperationCanceledException(ex.Message, ex, cancellationToken);
- }
- // cancellation hasn't been requested, rethrow the original WebException
- throw;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement