使用多个 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 报告两次而不是一次.
您需要稍微重写一下代码:
- 重构您的方法以采用
CancellationToken
而不是 CancellationTokenSource
。
- 将此令牌传递给
Task.Delay
、Task.ContinueWith
以及您的 PostGoingReport
方法(因此需要获取令牌,而不是源)
- start 方法应该构造一个新的源,获取它的令牌并按上述方式将其传入
您的 Start 方法应该如下所示:
cts = new CancellationTokenSource();
var token = cts.Token;
Task.Delay(10000, token).ContinueWith((x) => PostGoingReport(token), token);
这确保:
- 如果您在延迟结束前取消,延迟将取消(并且 continuewith 任务将不会执行)
- 如果您在延迟结束后但在执行 lambda 之前立即取消,continuewith 任务将不会调用它
- 您的
PostGoingReport
方法将使用其构建来源中的令牌,而不是实际执行时的任何当前令牌
我有一个创建新令牌源的 '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 报告两次而不是一次.
您需要稍微重写一下代码:
- 重构您的方法以采用
CancellationToken
而不是CancellationTokenSource
。 - 将此令牌传递给
Task.Delay
、Task.ContinueWith
以及您的PostGoingReport
方法(因此需要获取令牌,而不是源) - start 方法应该构造一个新的源,获取它的令牌并按上述方式将其传入
您的 Start 方法应该如下所示:
cts = new CancellationTokenSource();
var token = cts.Token;
Task.Delay(10000, token).ContinueWith((x) => PostGoingReport(token), token);
这确保:
- 如果您在延迟结束前取消,延迟将取消(并且 continuewith 任务将不会执行)
- 如果您在延迟结束后但在执行 lambda 之前立即取消,continuewith 任务将不会调用它
- 您的
PostGoingReport
方法将使用其构建来源中的令牌,而不是实际执行时的任何当前令牌