简体   繁体   中英

How to observe cancellation token?

Is there any other way how to observe cancellation token besides checking it in loop ?

while (moreToDo)
{
    // Poll on this property if you have to do
    // other cleanup before throwing.
    if (cancellationToken.IsCancellationRequested)
    {
        // Clean up here, then...
        cancellationToken.ThrowIfCancellationRequested();
     }

}

Example from: https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation

I want cancel task when method is running more then 5seconds. But processing VeryLong method can takes more then 5 seconds.

var cancelationTokenSource = new CancellationTokenSource(5000);
Task.Factory.StartNew(
     () =>
     {
         VeryLongMethod();

      }, cancelationTokenSource.Token
);

As I was suggested I tryed register callback, but after timeout, the very long method was still executed.

var cancellationTokenSource = new CancellationTokenSource(20000);

        await Task.Factory.StartNew
        (
            () =>
            {
                using (cancellationTokenSource.Token.Register(() =>
                {

                    Program.Console.WriteToConsole("Failed on timeout.");


                    try
                    {
                        cancellationTokenSource.Token.ThrowIfCancellationRequested();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Action was processed already");                            
                    }

                }))
                {
                    VeryLongMethod();
                }
            }, cancellationTokenSource.Token
        );

You can register a callback which will be called when the token is cancelled:

using(var reg = cancellationToken.Register(() => { /* cancellation logic */ }))
{
    // your code
}

Update: To your updated question, you can tell a cancellation token source that it must cancel its token after a period of time, like this:

cancelationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM