Friday, 5 May 2017

TPL 10 Cancellation

When working with tasks or threads there may come a time where you want to cancel a long running task before it completes. To do this you have to pass it a cancellation token which you control from a CancelationTokenSource. take a look at the following simple example.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace pc.CancellationTokenSource00
{
    class Program
    {
        static void Main(string[] args)
        {
            int option = -1;

            using (var cs = new CancellationTokenSource()) {
                var ct = cs.Token;
                do{
                    switch (option){
                        case 1:
                            Task.Run(() => {
                                while (true){
                                    Task.WaitAll(Task.Delay(1000));
                                    Console.WriteLine("thinking");
                                    ct.ThrowIfCancellationRequested();
                                }
                            }, ct).ContinueWith(tr=> {
                                tr.Exception.Handle(e => true);
                                Console.WriteLine("canceled");
                            },TaskContinuationOptions.OnlyOnCanceled);
                            break;
                        case 2:
                            cs.Cancel();
                            break;
                    }
                    Console.WriteLine("\n(1)Run (2)Cancel (0)Exit");

                } while (int.TryParse(Console.ReadKey().KeyChar.ToString(), out option)
                         && option != 0);
            }
        }
    }
}


What we do in the above is create never ending tasks the output the word "thinking" to the screen in one second intervals, when we singal the CancelationTokenSource that we want to cancel, it uses the CancellationToken to exit our task by throwing a cancellation request at which point we use our continueWith delegate marked to only fire when a cancelation occurs to notify our user.