2011-01-19 32 views
0

我有一个应用程序,我使用Paraller.ForEach()循环下载和处理大约7,800个URL。使用这种技术可以让我的计算机在大约4.5分钟内完成这项操作(平均用时将近28分钟)。Parallel.ForEach()....如何最好地从外部终止循环?

由于这是一个WinForms应用我允许用户通过简单地点击停止按钮,这将反过来设置的易失性布尔变量为“假”早“停止”过程中运行。在我的Parallel.ForEach()循环的顶部,我检查该变量的状态,如果它已被设置为'false',我只需调用ParallelLoopState.Stop()方法。如果ParallelLoopState尚未停止,我的下一个代码块将在循环内运行。

的伟大工程。使用这个实现已经经历了三个星期,我一直在使用它。

但是我只是在阅读并遇到“CancellationTokenSource”和“CancellationToken”类,并发现它们被设计为基本上执行相同的操作......以允许在外部取消并行循环。

谁能告诉我,如果他们预见到问题,我继续用我现有的实现?

Parallel.ForEach(searchList, (url, state) => 
{ 
    if (!this.isSearching) 
    { 
     state.Stop(); 

     OnSearchEvent(new SearchStatusEventArgs(SearchState.STOP_REQUESTED, ......)); 
    } 

    if (!state.IsStopped) 
    { 
     // continue on with regular processing ....... 
    } 
}); 
+2

相信YAGNI(你是不是要去需要它)原则上可以向上转型为“如果没坏,就不要修理它” :) – 2011-01-19 16:01:40

+0

我与你戴夫。由于我是使用并行扩展的新手,我只是想确保我没有构建某些隐藏的gremlins,但我还没有意识到隐藏的某些地方。没有什么比建立一座你认为值得信赖的桥更糟糕,只是意识到你站在地雷上。 – BonanzaDriver 2011-01-19 16:27:53

回答

2

看起来不错! CancellationTokenSource和CancellationToken确实适用于Tasks,尤其是在任务通过ContinueWith连接在一起的情况下。从那里,你可以询问令牌(线程安全),并抛出异常或退出线程完全相同的方式你已经这样做了。

除非你去了复杂的任务链和封闭的路线,然后我会说没有必要使事情变得复杂!