Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancellation of a task

I tried to run a simple example on the cancellation of a task like the one below

CancellationTokenSource tokenSource2 = new CancellationTokenSource();

CancellationToken token2 = tokenSource2.Token;


Task task2 = new Task(() =>
{
    for (int i = 0; i < int.MaxValue; i++)
    {
        token2.ThrowIfCancellationRequested();
        Thread.Sleep(100);
        Console.WriteLine("Task 2 - Int value {0}", i);
    }
}, token2);

task2.Start();

Console.WriteLine("Press any key to cancel the task");
Console.ReadLine();

tokenSource2.Cancel();
Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);

I expected that Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled); would print **"Task 2 cancelled? True"**, but it printed "False".

Do you know what happened? Is that the expected behaviour? Thanks.

EDIT: to ensure that the task hasn't completed before the cancellation request is called. I added the Console.ReadLine().

like image 211
Toan Nguyen Avatar asked Dec 15 '12 21:12

Toan Nguyen


People also ask

What is a cancellation token?

A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource.

How do I stop a running task in C#?

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.

What is the property of the task token to check the request of task cancellation?

The CancellationTokenSource token is used to signal that the Task should cancel itself. In the above case, the operation will just end when cancellation is requested via Cancel() method.


2 Answers

First, maybe you misunderstand what IsCanceled means? It doesn't mean “this Task is pending cancellation, so it should complete shortly”, it means “this Task has been canceled, it is now complete”.

If you didn't misunderstand that, think about what exactly the sequence of events is. What happens is this:

  1. ThrowIfCancellationRequested() is called, but the token wasn't canceled yet, so it doesn't throw.
  2. Thread.Sleep() is called, so the thread running the Task sleeps.
  3. Cancel() is called.
  4. IsCanceled is checked. The code in the Task didn't have a chance to realize that the token was canceled, so it's still running, so IsCanceled returns false.
  5. ThrowIfCancellationRequested() is called again, this time it throws, which actually cancels the Task.

This is why ISCanceled is returning false to you. If you want it to return true, you could add something like Thread.Sleep(150) before checking IsCanceled, or, even better, actually wait for the Task to complete.

like image 139
svick Avatar answered Sep 28 '22 07:09

svick


The Task ended before you call for cancellation, take a look at the following below this may help to shed some more light on how to resolve your issue

By reading from here http://social.msdn.microsoft.com/Forums/da-DK/parallelextensions/thread/9f88132a-f8bd-4885-ab63-645d7b6c2127 it seems that the token is used to cancel the task BEFORE the task is "really" started, but after it has been queued.

It's more a way to cancel a task that's scheduled to occur, but not started yet. Once the task is running, the only way to cancel it is cooperatively via your own checking within the method. Without this, you'd have to always start the task, then check it internally, which would add a lot of extra, unnecessary overhead

You can even read it from Cancellation token in Task constructor: why?

like image 35
MethodMan Avatar answered Sep 28 '22 07:09

MethodMan