How do I abort/cancel TPL Tasks? How do I abort/cancel TPL Tasks? multithreading multithreading

How do I abort/cancel TPL Tasks?


You can't. Tasks use background threads from the thread pool. Also canceling threads using the Abort method is not recommended. You may take a look at the following blog post which explains a proper way of canceling tasks using cancellation tokens. Here's an example:

class Program{    static void Main()    {        var ts = new CancellationTokenSource();        CancellationToken ct = ts.Token;        Task.Factory.StartNew(() =>        {            while (true)            {                // do some heavy work here                Thread.Sleep(100);                if (ct.IsCancellationRequested)                {                    // another thread decided to cancel                    Console.WriteLine("task canceled");                    break;                }            }        }, ct);        // Simulate waiting 3s for the task to complete        Thread.Sleep(3000);        // Can't wait anymore => cancel this task         ts.Cancel();        Console.ReadLine();    }}


Aborting a Task is easily possible if you capture the thread in which the task is running in. Here is an example code to demonstrate this:

void Main(){    Thread thread = null;    Task t = Task.Run(() =>     {        //Capture the thread        thread = Thread.CurrentThread;        //Simulate work (usually from 3rd party code)        Thread.Sleep(1000);        //If you comment out thread.Abort(), then this will be displayed        Console.WriteLine("Task finished!");    });    //This is needed in the example to avoid thread being still NULL    Thread.Sleep(10);    //Cancel the task by aborting the thread    thread.Abort();}

I used Task.Run() to show the most common use-case for this - using the comfort of Tasks with old single-threaded code, which does not use the CancellationTokenSource class to determine if it should be canceled or not.


Like this post suggests, this can be done in the following way:

int Foo(CancellationToken token){    Thread t = Thread.CurrentThread;    using (token.Register(t.Abort))    {        // compute-bound work here    }}

Although it works, it's not recommended to use such approach. If you can control the code that executes in task, you'd better go with proper handling of cancellation.