Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canceling a task

I have a task which i need to cancel if the wait time is over. For instance

var t = Task.Factory.StartNew(() => 
{
  Thread.Sleep(5000) // some long running task
  "do something"
});
Task.WaitAll(new[] {t}, 1000);

But it seems the task still keeps working. I tried using CancellationTokenSource but that didnt seem to work as well.

I confirmed this using the following snippet

static void Main(string[] args)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            var t = Task.Factory.StartNew(() => {
                Thread.Sleep(5000);
                Console.WriteLine("Still working");
            }, cancellationTokenSource.Token);

            Task.WaitAll(new[] {t}, 1000);

            cancellationTokenSource.Cancel();

            Console.ReadLine();
        }

Console displays "Still working". I thought the task would have been cancelled.

I am sure I am missing something. What am i missing? Thanks.

like image 875
stackoverflowuser Avatar asked Mar 02 '11 19:03

stackoverflowuser


People also ask

How can you handle a canceled task?

In this articleCreate and start a cancelable task. Pass a cancellation token to your user delegate and optionally to the task instance. Notice and respond to the cancellation request in your user delegate. Optionally notice on the calling thread that the task was canceled.

How do I cancel a CancellationToken?

A CancellationToken can only be created by creating a new instance of CancellationTokenSource . CancellationToken is immutable and must be canceled by calling CancellationTokenSource. cancel() on the CancellationTokenSource that creates it. It can only be canceled once.

How do you start and end a task in C#?

StartNew() . Inside the task, there is a while loop that performs processing as long as the task hasn't been canceled. From my understanding, if cancellationToken. IsCancellationRequested is ever true, the else within my while loop will run and the task will stop.


1 Answers

Cancellation tokens don't magically cancel anything. They just allow you to check for cancellation in a standardized way, e.g. via ThrowIfCancellationRequested.

So typically you'd have some task which needs to perform a lot of work. It periodically calls ThrowIfCancellationRequested, and then any code which needs to cancel the task will call Cancel on the CancellationTokenSource when it needs to. The task will throw when it next checks for cancellation, and all will be well.

It sounds like you're looking for a non-cooperative cancellation - and that would be dangerous, for exactly the same reasons that the normal Thread.Abort is dangerous. It's cleaner to let the task pick the points at which it will allow itself to be cancelled.

like image 99
Jon Skeet Avatar answered Oct 08 '22 22:10

Jon Skeet