我对使用cancellationToken和cancelationTokenSource取消任务有疑问:
通常的方法如下:
var cts = new CancellationTokenSource();
var t = Task.Run(() => {
while(true)
{
if (!cts.IsCancellationRequested)
{ //do stuff }
}
}, cts.Token);
因此,while循环一直持续到请求令牌为止。
今天,在研究Cancel()
方法时,我发现您可以使用Register()
方法来定义其他代码,以便在请求令牌时运行其他代码,所以我想知道,如果编写了这样的代码怎么办:
var cts = new CancellationTokenSouce();
token=cts.Token;
token.Register(
() => {
//do something to manage the cancel call
return;
};
)
var t = Task.Run(() => {
//do stuff
}, cts.Token);
这样做,与CancellationToken
相关的任务将立即停止执行,而不必像通常的实现那样完成当前的迭代工作。我的问题是:这是立即停止Task
的正确方法还是有更好的方法?
答案 0 :(得分:5)
Register
不会导致任务停止执行,而只是通知已请求取消。 Register
的主要目的是能够取消不支持CancellationToken
但具有自己的取消机制或可以间接取消(例如通过关闭套接字)的异步操作。 Stephen Toub here还描述了一些技巧,说明如何使用Register
取消不可取消的任务。但是,如果您控制应取消的任务的执行,则您有责任提供一种取消执行的机制。没有最好的方法来取消任何任务-有些任务可以立即取消(可以使用ThrowIfCancellationRequested
),有些任务可能需要一些额外的处理(您需要检查请求取消的内容,执行某些操作然后抛出例外)。