C# 如何在不经常检查取消令牌的情况下取消任务
我看到的许多关于这个主题的帖子都建议您必须经常检查令牌是否已被取消。我正在做的工作并不是全部打包在一个循环中,所以我必须在整个代码中进行标记检查 有没有类似于ThreadAboutException的东西我可以直接捕捉到 我甚至不确定取消令牌是否是我应该在这里使用的C# 如何在不经常检查取消令牌的情况下取消任务,c#,wpf,C#,Wpf,我看到的许多关于这个主题的帖子都建议您必须经常检查令牌是否已被取消。我正在做的工作并不是全部打包在一个循环中,所以我必须在整个代码中进行标记检查 有没有类似于ThreadAboutException的东西我可以直接捕捉到 我甚至不确定取消令牌是否是我应该在这里使用的 // UI Thread CancellationToken token = new ... private async void StartWorkButton_Click(object sender, RoutedEventA
// UI Thread
CancellationToken token = new ...
private async void StartWorkButton_Click(object sender, RoutedEventArgs e)
{
await Dispatcher.BeginInvoke(async () =>
{
await myWorkObject.LotsOfWorkAsync(token);
}
}
private async void StopWorkButton_Click(object sender, RoutedEventArgs e)
{
token.Cancel();
}
public override async Task LotsOfWorkAsync(CancellationToken token)
{
... work here
if(cancelToken.IsCancellationRequested)
{
return;
}
... more work
if(cancelToken.IsCancellationRequested)
{
return;
}
... some other work
if(cancelToken.IsCancellationRequested)
{
return;
}
... some work in a loop
foreach(var i in items)
{
if(cancelToken.IsCancellationRequested)
{
return;
}
}
... even more work
}
有时我也会遇到同样的问题,但在完全异步的场景中很容易实现:只需将令牌传递给LotusOfWorkAsync中调用的每个异步方法,就没有安全的替代方法。您必须定期检查,以便取消是合作的。请参阅标记的副本,以及相关的@PeterDuniho感谢您的回答。我想使用任务这是唯一/正确的检查方法?如果没有,那么回到使用专用线程和ThreadAbort将是获得所需结果的唯一其他选项?“我想使用任务这将是唯一/正确的检查方式?”--您可以使用任何您喜欢的信号机制。重要的是,您正在轮询信号。“使用专用线程和线程中止将是唯一的其他选项”--中止线程不是一个选项。时期无论您使用的线程机制如何,这都是不安全的。TPL通过与更通用的“异步”习惯用法集成,改变了线程的顶级语义,但非合作取消的危害对TPL来说并不新鲜。它们一直存在于每种线程方法中。这里有一个有趣的巧合:就在今天,Raymond Chen发布了一个例子,说明为什么中止线程是一个如此糟糕的主意:。在写了我之前的评论之后,我才刚刚看到这篇文章,但它包含了与我提供的警告完全相同的警告(在标记的重复问题中),以及一个具体的例子,说明了当你中止一个线程时会断开的事情(有无数这样的例子)。