【问题标题】:Immediate Task Cancellation立即取消任务
【发布时间】:2019-02-05 04:25:48
【问题描述】:

我有一个关于使用cancellationToken 和cancellationTokenSource 取消任务的问题:

通常的方式如下:

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 的正确方法还是有更好的方法?

【问题讨论】:

    标签: c# .net task .net-standard cancellation


    【解决方案1】:

    Register 不会导致任务停止执行,它只是通知已请求取消。 Register 的主要目的是能够取消不支持 CancellationToken 但有自己的取消机制或可以间接取消的异步操作(例如通过关闭套接字)。 Stephen Toub here 还描述了一些技巧,说明如何使用 Register 取消不可取消的任务。但是,如果您控制应该取消的任务的执行,则您有责任提供一种取消执行的机制。没有最好的方法来取消任何任务——有些任务可以立即取消(你可以使用ThrowIfCancellationRequested),有些可能需要一些额外的处理(你需要检查是否请求取消,做一些事情然后抛出异常)。

    【讨论】:

    • 好的,所以如果我理解正确,我的想法是我在Register() 中输入的返回值将停止//do something to manage the cancel call 部分,而不是与令牌关联的任务,对吧?我知道Register() 本身不会停止任务,我想知道是否可以使用 [Register()] 中的代码来停止它[任务]。
    • 在大部分情况下,Register 和任务内部的代码在不同的线程中执行。所以你不能直接停止Register 中的任务执行。您需要在任务中添加一些代码来对取消信号做出反应,当然您可以从Register 发送此信号,但在您的情况下,这有点矫枉过正,因为您只需实现逻辑来验证任务中的取消令牌状态.并且令牌不与它们解耦的任何任务相关联 - 相反,它可以作为参数传递给任务执行方法。
    猜你喜欢
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多