立即取消任务
Immediate Task Cancellation
我对使用 cancellationToken 和 cancellationTokenSource 取消任务有疑问:
通常的做法如下:
var cts = new CancellationTokenSource();
var t = Task.Run(() => {
while(true)
{
if (!cts.IsCancellationRequested)
{ //do stuff }
}
}, cts.Token);
因此,while 循环一直持续到请求令牌为止。
今天在研究Cancel()
方法的时候发现可以用Register()
方法在请求token的时候定义其他代码到运行,所以我想知道,如果一个写了这样的东西:
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
关联的任务将立即停止执行,而不是像通常的实现那样必须完成当前的 for 迭代。我的问题是:这是立即停止 Task
的正确方法还是有更好的方法?
Register
不会导致任务停止执行,它只是一个已请求取消的通知。 Register
的主要目的是能够取消不支持 CancellationToken
但有自己的取消机制或可以间接取消(例如通过关闭套接字)的异步操作。还有一些技巧由 Stephen Toub here 描述如何使用 Register
取消不可取消的任务。但是,如果您控制应该取消的任务的执行,则您有责任提供一种取消执行的机制。没有如何取消任何任务的最佳方法 - 有些任务可以立即取消(你可以使用 ThrowIfCancellationRequested
),有些可能需要一些额外的处理(你需要检查是否请求取消,做一些事情然后抛出例外)。
我对使用 cancellationToken 和 cancellationTokenSource 取消任务有疑问:
通常的做法如下:
var cts = new CancellationTokenSource();
var t = Task.Run(() => {
while(true)
{
if (!cts.IsCancellationRequested)
{ //do stuff }
}
}, cts.Token);
因此,while 循环一直持续到请求令牌为止。
今天在研究Cancel()
方法的时候发现可以用Register()
方法在请求token的时候定义其他代码到运行,所以我想知道,如果一个写了这样的东西:
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
关联的任务将立即停止执行,而不是像通常的实现那样必须完成当前的 for 迭代。我的问题是:这是立即停止 Task
的正确方法还是有更好的方法?
Register
不会导致任务停止执行,它只是一个已请求取消的通知。 Register
的主要目的是能够取消不支持 CancellationToken
但有自己的取消机制或可以间接取消(例如通过关闭套接字)的异步操作。还有一些技巧由 Stephen Toub here 描述如何使用 Register
取消不可取消的任务。但是,如果您控制应该取消的任务的执行,则您有责任提供一种取消执行的机制。没有如何取消任何任务的最佳方法 - 有些任务可以立即取消(你可以使用 ThrowIfCancellationRequested
),有些可能需要一些额外的处理(你需要检查是否请求取消,做一些事情然后抛出例外)。