我有一个应用程序,我使用Paraller.ForEach()循环下载并处理大约7,800个URL。使用这种技术,我的计算机可以在大约4.5分钟内完成此操作(平均需要花费大约28分钟)。
由于这是在WinForms应用程序中运行的,我允许用户通过简单地单击停止按钮来提前“停止”该过程,然后停止按钮将挥发性布尔变量设置为“false”。在我的Parallel.ForEach()循环的顶部,我检查该变量的状态,如果它已被设置为'false',我只需调用ParallelLoopState.Stop()方法。循环中的下一个代码块仅在ParallelLoopState尚未停止时才会运行。
效果很好。在我使用它的3周内使用此实现经历了零问题。
但我刚刚阅读并遇到了“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 .......
}
});
答案 0 :(得分:2)
对我来说很好看! CancellationTokenSource和CancellationToken实际上与Tasks一起使用,特别是在通过ContinueWith
将任务链接在一起的情况下。从那里,您可以询问令牌(线程安全)并抛出异常或退出中的线程与您已经完成的相同。
除非你沿着复杂的任务链和闭包的路走下去,否则我说没有必要让事情复杂化!