Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何观察取消令牌?_C#_.net - Fatal编程技术网

C# 如何观察取消令牌?

C# 如何观察取消令牌?,c#,.net,C#,.net,除了在循环中检查取消令牌外,还有其他方法可以观察取消令牌吗 while (moreToDo) { // Poll on this property if you have to do // other cleanup before throwing. if (cancellationToken.IsCancellationRequested) { // Clean up here, then... cancellationToken

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

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

}
示例来自:

我想在方法运行超过5秒时取消任务。但处理VeryLong方法可能需要5秒以上的时间

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

      }, cancelationTokenSource.Token
);
正如我被建议的那样,我尝试了寄存器回调,但在超时之后,仍然执行了很长的方法

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
ThrowifcCancellationRequested
是我们知道必须取消的唯一方法

这意味着,在当前基于asyncwait任务的设计中,如果调用方想要取消,可取消方法必须定期检查自己,并自己提供一个退出点。如果不立即将方法更改为与取消系统“合作”,则无法直接取消方法


它本身不需要一个循环,但无论如何检查都需要某种形式的池。循环是一种典型的构造,但可以使用其他任何东西。

您可以注册一个回调,该回调将在取消令牌时调用:

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

更新:对于您更新的问题,您可以告诉取消令牌源它必须在一段时间后取消其令牌,如下所示:

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

当然可以。您也可以在循环外检查它。不清楚您试图解决的是什么问题。如果我没记错的话,如果您取消任务,
AggregateException
将被抛出。。不确定您的用例是什么。。因此,不能说这种方法是一个好的建议。更新问题的可能重复您可以在5秒钟后取消任务,假设“veryLongMethod()”是某种重复任务,并且您正在反复检查“IsCancellationRequested”。如果不是,则说您的“veryLongMethod()”正在读取一个大的文本文件,因此即使您取消取消令牌,任务也不会停止,因为它没有检查此状态。这不太正确,请参阅重复问题I linked.Hi。我更新了关于您提出的解决方案的问题。你能看一下吗?好的,但是你怎么取消VeryLongMethod()呢?你没有为它传递代币,你必须用它做点什么,它不会自动取消。我现在明白了。