本文介绍了如何观察取消令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了在循环中检查取消令牌以外,还有其他方法可以观察取消令牌吗?

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();
     }

}

示例来自: https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation

当方法运行超过5秒时,我想取消任务.但是处理VeryLong方法可能要花费5秒钟以上的时间.

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
        );

推荐答案

总之,没有.定期池化是我们检查任务是否要取消的唯一方法. CancellationToken 不提供任何其他通知方式来检查它, IsCancellationRequested ThrowIfCancellationRequested 是我们唯一必须取消的方式

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.

这篇关于如何观察取消令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 03:50