Troopers Troopers - 5 days ago 7
C# Question

Tasks cancellation and continue with

I'm perplex on the cancellation of several tasks and continue with a task to display result.
According to what I understood, this program should display


Tasks canceled


CancellationTokenSource cts = new CancellationTokenSource();
List<Task> tasks = new List<Task>();
for(int i= 0; i<3; i++)
{
tasks.Add(Task.Run(() =>{
while(!cts.Token.IsCancellationRequested)
Thread.Sleep(500);

// Uncomment this to see 'Tasks canceled' in the result
//if(cts.Token.IsCancellationRequested)
// cts.Token.ThrowIfCancellationRequested();
},cts.Token));
}

Task.WhenAll(tasks).ContinueWith(task =>
{
if(task.IsCanceled)
Console.WriteLine("Tasks canceled");
if(task.IsCompleted)
Console.WriteLine("Tasks completed");
});
Thread.Sleep(2000);
cts.Cancel();


Unfortunately it display


Tasks completed


If i uncomment the throwing of cancel exception the program display


Tasks canceled

Tasks completed


Why? it seems that I missed something but I do not see what...

Answer

In first case this is what your code says it to do - stop looping when cancellation is requesting. After it exits loop, there is nothing more to execute hence task is complete.

By design to really cancel task, you need to throw exception to change execution flow. In fact, 'if' statement is not needed in your code sample - that 'ThrowIfCancellationRequested' method will handle this check by itself and will throw exception if cancellation has been requested.

Regarding last part, here is excerpt from MSDN:

IsCompleted will return true when the task is in one of the three final states: RanToCompletion, Faulted, or Canceled.

https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.iscompleted(v=vs.110).aspx

So even if task was cancelled, it is complete.

Comments