24

Are there any benefits for using a CancellationTokenSource over a volatile boolean field for signalling a Task to finish?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Yoav
  • 3,326
  • 3
  • 32
  • 73
  • 1
    A `CancellationToken` isn't meant to signal a thread to finish, it's meant to tell a `Task` to *cancel* it's operation. If you want a `Task` to return, simply use a `return` statement. – Yuval Itzchakov May 04 '15 at 07:42
  • Since there are a load of standard C# threading classes (including Task) which use `CancellationTokenSource` in their interfaces, then that's what you should use. – Matthew Watson May 04 '15 at 07:43
  • @YuvalItzchakov if I'm not mistaken, I still need to handle the way my tasks finish when using a CancelationTokeSource (i.e return or break) – Yoav May 04 '15 at 07:50
  • 1
    `CancellationToken` is the only way you can transition your `Task` into a `Canceled` state. returning on a `bool` would transition it to a `Completed` state – Yuval Itzchakov May 04 '15 at 07:51
  • @YuvalItzchakov Well, you could `throw TaskCanceledException` which would cause that to happen - but it would be a bit of an odd thing to do because the exception wouldn't contain a meaningful `CancellationToken`. – Matthew Watson May 04 '15 at 08:02
  • @MatthewWatson That wouldn't much sense though, would it? :) – Yuval Itzchakov May 04 '15 at 08:04
  • @MatthewWatson Simply throwing `TaskCanceledException` isn't enough. You need to pass a cancellation token, and same token has to be passed when you have started the task. Otherwise, Task will not be started, but faulted. – Sriram Sakthivel May 04 '15 at 08:18
  • Arguably a duplicate of [Difference between CancellationTokenSource and exit flag for Task loop exit](http://stackoverflow.com/q/27950848/3538012) – Peter Duniho May 04 '15 at 08:21

1 Answers1

29

Of course yes. There are many. I'll list few.

  • CancellationToken supports callbacks. You can be notified when the cancellation is requested.
  • CancellationToken supports WaitHandle which you could wait for indefinitely or with a timeout.
  • You can schedule the cancelation of CancellationToken using CancellationTokenSource.CancelAfter method.
  • You can link your CancellationToken to another, so that when one is cancelled another can be considered as cancelled.
  • By Task if you mean System.Threading.Tasks.Task a volatile boolean cannot transition the state of the Task to cancelled but CancellationToken can.
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • And also [here's an interesting article from Eric Lippert](http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx) explaining why he thinks you shouldn't use `volatile`. – Matthew Watson May 04 '15 at 07:50
  • That's very comprehensive, Thanks. – Yoav May 04 '15 at 08:05
  • 7
    @MatthewWatson: to be fair, Eric's main objection seems to be that it's often very difficult to use `volatile` correctly, and that `lock` usually has sufficient performance, and is semantically easier to understand. A simple `volatile` flag to signal the termination of a task, while undesirable for other reasons, isn't what Eric seems to be concerned with in his article. – Peter Duniho May 04 '15 at 08:26
  • 2
    MatthewWatson's link is outdated, I update the link here ["Atomicity, volatility and immutability are different, part three"](https://ericlippert.com/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three/) – Louis Go Mar 11 '20 at 09:10
  • I think @LouisGo response is the real answer here, better than the answer. Reading the answer, I think "Ok, I don't care, I'll use volatile." But reading Eric Lippert's blog, I think "Clearly there is complexity that I don't understand. I should use `Interlocked`, or `CancellationToken` instead." – Edward Ned Harvey Oct 24 '21 at 21:55