使用多个 CancellationSourceTokens 取消任务

Cancelling a Task, using multiple CancellationSourceTokens

我有一个创建新令牌源的 'Start' 按钮和一个取消令牌源的 'Stop' 按钮。

我在 class:

中的函数之外定义了取消令牌源
public static CancellationTokenSource cts;

当您单击开始按钮时,我将以下任务设置为 运行 10 秒后开始:

cts = new CancellationTokenSource();
Task.Delay(10000).ContinueWith((x) => PostGoingReport(cts));

在我正在检查的方法中,确保令牌在 运行ning:

之前没有被取消
if (cts.IsCancellationRequested )
{
    return;
}

在停止按钮中我有:

cts.Cancel();

当您单击开始按钮,然后单击停止按钮时,它会按预期工作并且不会 post 报告。

但是,如果您单击启动按钮,然后停止,然后再次启动按钮,任务 运行s 两次。 这是因为我正在创建相同的 CancellationTokenSource 实例,因此不再请求令牌源进行取消。

有什么方法可以让任务链接到特定的令牌源?

我问这个的原因是因为我的应用程序 'Sleeps' 取消了某些时间之间的所有任务然后醒来,它似乎醒来并且 post 报告两次而不是一次.

您需要稍微重写一下代码:

  1. 重构您的方法以采用 CancellationToken 而不是 CancellationTokenSource
  2. 将此令牌传递给 Task.DelayTask.ContinueWith 以及您的 PostGoingReport 方法(因此需要获取令牌,而不是源)
  3. start 方法应该构造一个新的源,获取它的令牌并按上述方式将其传入

您的 Start 方法应该如下所示:

cts = new CancellationTokenSource();
var token = cts.Token;
Task.Delay(10000, token).ContinueWith((x) => PostGoingReport(token), token);

这确保:

  1. 如果您在延迟结束前取消,延迟将取消(并且 continuewith 任务将不会执行)
  2. 如果您在延迟结束后但在执行 lambda 之前立即取消,continuewith 任务将不会调用它
  3. 您的 PostGoingReport 方法将使用其构建来源中的令牌,而不是实际执行时的任何当前令牌