2012-11-29 53 views
5

我有不同的任务从不同的文件中读取并找到一个单词。我已经把它们放入一个任务数组,我开始了WaitAny方法如下:如何在c中完成一个任务时停止所有任务#

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

我想尽快的任务之一完成停止所有其他任务(当它开创这个词它完成)。目前,有了waitany,我可以知道一项任务何时完成,但我不知道如何知道哪一项已完成,以及如何停止其他任务。 达到此目的的最佳方法是什么?

+0

完成的任务是否在某处留下了结果?这可能包括确定任务。完成的第一个任务还可以设置一个事件,由其主循环中的每个任务检查,这会导致所有其他任务退出。在mySearch.Invoke中的 – HABO

+0

,它们应该是循环逐字地循环。 然后,您可以添加一个标志,以便在标志发出信号时循环中断,当任何任务发现该字时,可以发信号通知标志 – ComfortablyNumb

回答

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当源是通过调用token.ThrowIfCancellationRequested()

2

创建任务时,你可以通过一个CancelationToken取消您可以强制令牌抛出OperationCanceledException。当其中一个任务完成时设置此令牌。 这将导致剩余的任务使用此令牌到not execute。正在运行的任务可能会收到OperationCanceledException并停止。

1

我强烈建议您阅读Stephen Toub的How do I cancel non-cancelable async operations?。基本上你需要做的是取消所有这些任务,但目前你没有任何机制来取消它们。

理想的方法是在foreach之前创建CancellationTokenSource,将CancellationToken从该源传递给每个子任务,定期检查该令牌并在您注意到它指示取消时停止工作。然后您可以取消WhenAny延续中的令牌源。

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

相关问题