How to Use the Cancellationtoken Property

How to use the CancellationToken property?

You can implement your work method as follows:

private static void Work(CancellationToken cancelToken)
{
while (true)
{
if(cancelToken.IsCancellationRequested)
{
return;
}
Console.Write("345");
}
}

That's it. You always need to handle cancellation by yourself - exit from method when it is appropriate time to exit (so that your work and data is in consistent state)

UPDATE: I prefer not writing while (!cancelToken.IsCancellationRequested) because often there are few exit points where you can stop executing safely across loop body, and loop usually have some logical condition to exit (iterate over all items in collection etc.). So I believe it's better not to mix that conditions as they have different intention.

Cautionary note about avoiding CancellationToken.ThrowIfCancellationRequested():

Comment in question by Eamon Nerbonne:

... replacing ThrowIfCancellationRequested with a bunch of checks for IsCancellationRequested exits gracefully, as this answer says. But that's not just an implementation detail; that affects observable behavior: the task will no longer end in the cancelled state, but in RanToCompletion. And that can affect not just explicit state checks, but also, more subtly, task chaining with e.g. ContinueWith, depending on the TaskContinuationOptions used. I'd say that avoiding ThrowIfCancellationRequested is dangerous advice.

What is the use of passing CancellationToken to Task Class constructor?

UPDATE:
The following msdn question describes the reason:

Passing a token into StartNew associates the token with the Task.
This has two primary benefits:

  1. If the token has cancellation
    requested prior to the Task starting to execute, the Task won't
    execute. Rather than transitioning to Running, it'll immediately
    transition to Canceled. This avoids the costs of running the task if
    it would just be canceled while running anyway.

  2. If the body of the
    task is also monitoring the cancellation token and throws an
    OperationCanceledException containing that token (which is what
    ThrowIfCancellationRequested does), then when the task sees that OCE,
    it checks whether the OCE's token matches the Task's token. If it
    does, that exception is viewed as an acknowledgement of cooperative
    cancellation and the Task transitions to the Canceled state (rather
    than the Faulted state).

How to cancel a CancellationToken

As the documentation state, you need to call the cancel method from the source object. Example code is included in the link you provided. Here are the relevant sections:

// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource();
previouslyProvidedToken = source.Token;
...
source.Cancel();

CancellationToken Struct

how can I, in possession of only a CancellationToken, cancel it?

Edit: I wrote this years ago and revisiting it I don't know if its actually valid either when written or right now. Leaving it here as-is for posterity.

Without a reference to the source you cannot cancel a token. That doesn't mean that you need the CancellationTokenSource that first spawned the token. When given a CancellationToken, you can create a new instance of the token source, assign it's token to the provided token, and cancel it. All other parties that can read this token will see that it's cancellation has been requested.

How to observe cancellation token?

In short, no. Pooling periodically is the only way we can ever check if a task is intended to be cancelled. CancellationToken doesn't provides any other means of notification to check for it, IsCancellationRequested and ThrowIfCancellationRequested being the only ways we can ever know we must cancel.

That implies that with the current async-await task-based design, cancellable methods must periodically check on themselves if the caller wants to cancel, and provide an exit point themselves. There is no direct way of cancelling a method without changing it to "cooperate" with the cancellation system right now.

It doesn't needs a loop in itself, but some form of pooling is needed for the check anyway. A loop is a typical construct, but anything else can be used.

new CancellationToken() and IsCancellationRequested without CancellationTokenSource

new CancellationToken() - or equivalently CancellationToken.None produces a cancellation token which never will be cancelled.

It is useful when you call a method expecting a CancellationToken, but your code does never intend to cancel the task.



Related Topics



Leave a reply



Submit