OK, my questions is really simple. Why this code does not throw TaskCancelledException
?
static void Main() { var v = Task.Run(() => { Thread.Sleep(1000); return 10; }, new CancellationTokenSource(500).Token).Result; Console.WriteLine(v); // this outputs 10 - instead of throwing error. Console.Read(); }
But this one works
static void Main() { var v = Task.Run(() => { Thread.Sleep(1000); return 10; }, new CancellationToken(true).Token).Result; Console.WriteLine(v); // this one throws Console.Read(); }
The CancellationToken is used in asynchronous task. 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.
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. Token property.
CancellationTokenSource is quite a heavyweight object and its not normally cancelled; however it can't be pooled or reused because its registrations cannot be cleared.
In this article, we will learn How to cancel or interrupt the Long Running Task using a Cancellationtokensource method in . NET 4.0. In this article, we are going to learn how to cancel or interrupt the Long Running Task using the Cancellationtokensource method in .
Cancellation in Managed Threads:
Cancellation is cooperative and is not forced on the listener. The listener determines how to gracefully terminate in response to a cancellation request.
You didn't write any code inside your Task.Run
method to access your CancellationToken
and to implement cancellation - so you effectively ignored the request for cancellation and ran to completion.
There is a difference in canceling a running task, and a task scheduled to run.
After the call to the Task.Run method, the task is only scheduled, and probably have not been executed yet.
When you use the Task.Run(..., CancellationToken) family of overloads with cancellation support, the cancellation token is checked when the task is about to run. If the cancellation token has IsCancellationRequested set to true at this time, an exception of the type TaskCanceledException is thrown.
If the task is already running, it is the task's responsibility to call the ThrowIfCancellationRequested method, or just throw the OperationCanceledException.
According to MSDN, it's just a convenience method for the following:
if (token.IsCancellationRequested) throw new OperationCanceledException(token);
Note the different kind of exception used in this two cases:
catch (TaskCanceledException ex) { // Task was canceled before running. } catch (OperationCanceledException ex) { // Task was canceled while running. }
Also note that TaskCanceledException
derives from OperationCanceledException
, so you can just have one catch
clause for the OperationCanceledException
type:
catch (OperationCanceledException ex) { if (ex is TaskCanceledException) // Task was canceled before running. // Task was canceled while running. }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With