我有不同的任务从不同的文件中读取并在其中找到一个单词。我已将它们放入一个任务数组中,我从waitAny方法开始如下:
foreach (string file in filesList)
{
files[i] = Task.Factory.StartNew(() =>
{
mySearch.Invoke(file);
});
i++;
}
System.Threading.Tasks.Task.WaitAny(files);
我想在其中一个任务完成后立即停止所有其他任务(它在找到该单词时结束)。目前,有了waitany,我可以知道一个任务什么时候结束,但我不知道怎么知道哪一个完成了以及如何停止其他任务。 实现这一目标的最佳方法是什么?
答案 0 :(得分:2)
您可以使用所有任务将共享的单CancellationToken
。内部mySearch.Invoke
方法验证token.IsCancellationRequested
的值以取消任务。当某项任务完成后,将通过CancellationTokenSource.Cancel()
取消其他任务。
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
foreach (string file in filesList)
{
// pass cancellation token to your task
files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token);
i++;
}
Task.WaitAny(files);
tokenSource.Cancel();
BTW 您可以通过调用OperationCanceledException
token.ThrowIfCancellationRequested()
答案 1 :(得分:2)
创建任务时,您可以传递 CancelationToken 。在其中一个任务完成时设置此标记。
这将导致使用此令牌的剩余任务not execute。正在运行的任务可以收到OperationCanceledException
并停止。
答案 2 :(得分:1)
我强烈建议阅读Stephen Toub的How do I cancel non-cancelable async operations?。基本上你需要做的是取消所有这些任务,但目前你没有机制取消它们。
理想的方法是在foreach之前创建CancellationTokenSource
,将CancellationToken
从该源传递给每个子任务,定期检查该令牌,并在发现它时指示停止工作消除。然后,您可以在WhenAny
续集中取消令牌来源。
如果这不是一个选项,你需要决定实际停止任务是否很重要(实际上,这是不可能完成的),或者你只需要继续使用代码而不等待它们完成(这很容易做到。)