sashoalm sashoalm - 5 months ago 14
C# Question

Can a TPL task that doesn't check whether it's cancelled, still be cancelled?

I thought that the CancellationToken/CancellationTokenSource system worked a bit like a C++

volatile bool bFlagCancelled
, meaning that cancellation is voluntary on the part of the task, and relies on the task itself to check from time to time whether it is cancelled and throw an exception, either explicitly or by calling

But if I call Cancel immediately after
, the task stops, and calling
throws a

For example, for this code:

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Task task = Task.Factory.StartNew(
() =>
Console.WriteLine("start sleep");
Console.WriteLine("sleep ended");
, token);
// Thread.Sleep(1);
Console.WriteLine("start wait");
Console.WriteLine("wait ended");

I get this output:

start wait
Exception: System.AggregateException: One or more errors occurred. ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.

But if I uncomment
// Thread.Sleep(1);
, then the behavior changes and I get this output:

start sleep
start wait
sleep ended
wait ended

Now I thought maybe this is because
hasn't been called yet, but as far as I understand it,
before returning - that's why it doesn't have the synchronization cost and is recommended vs creating a
new Task
and calling

So then this means in some situations, a task will cancel spontaneously, even without checking the cancellation token. Is this the only situation where this happens, or are there more scenarios where this happens?


Task.Factory.StartNew schedules the task before returning, but it doesn't mean the task actually started to execute. So there is still room to cancel the task, if the TaskScheduler accepts it (internally, the TaskScheduler.TryDequeue method is called. The task can be marked as cancelled if it returns true).