如何在c#中完成任务后停止所有任务

时间:2012-11-29 16:02:41

标签: c# parallel-processing task multiprocessing

我有不同的任务从不同的文件中读取并在其中找到一个单词。我已将它们放入一个任务数组中,我从waitAny方法开始如下:

foreach (string file in filesList)
        {
            files[i] = Task.Factory.StartNew(() =>
            {
                mySearch.Invoke(file);
            });
            i++;
        }
        System.Threading.Tasks.Task.WaitAny(files);

我想在其中一个任务完成后立即停止所有其他任务(它在找到该单词时结束)。目前,有了waitany,我可以知道一个任务什么时候结束,但我不知道怎么知道哪一个完成了以及如何停止其他任务。  实现这一目标的最佳方法是什么?

3 个答案:

答案 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续集中取消令牌来源。

如果这不是一个选项,你需要决定实际停止任务是否很重要(实际上,这是不可能完成的),或者你只需​​要继续使用代码而不等待它们完成(这很容易做到。)