除了在循环中检查取消令牌以外,还有其他方法可以观察取消令牌吗?
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秒钟以上。
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
);
答案 0 :(得分:1)
您可以注册一个回调,当令牌被取消时将被调用:
using(var reg = cancellationToken.Register(() => { /* cancellation logic */ }))
{
// your code
}
更新:对于您更新的问题,您可以告诉取消令牌来源,一段时间后必须取消其令牌,如下所示:
cancelationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));
答案 1 :(得分:0)
简而言之,不。定期池化是我们检查任务是否打算取消的唯一方法。 CancellationToken
不提供任何其他通知方式来检查它,IsCancellationRequested
和ThrowIfCancellationRequested
是我们唯一知道必须取消的方式。
这意味着在当前基于异步等待任务的设计中,可取消方法必须定期检查自身,以了解调用者是否要取消并自行提供退出点。现在,如果不将其更改为与取消系统“合作”,就没有直接取消方法的方法。
它本身不需要循环,但是无论如何,检查都需要某种形式的合并。循环是典型的构造,但可以使用其他任何东西。