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.