2016-09-29 137 views
2

我有这样的代码来开始并行ForEach循环:如何停止Parallel.ForEach循环?

Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, item => { 
    if (CallToStop == true) 
     { 
      //Code here to stop the loop! 
     }   
    internalProcessStart(item); 
}); 

我有一些代码,将检查是否有一个叫停止线程,然后我想break;的代码,但是这并未与Parallel不兼容。

我发现了相同的question by someone else,但他们的代码与我的代码略有不同,我不确定在哪里放置ParallelLoopState state

谢谢!

+0

你可以在ForEach循环体中编辑吗? –

+0

@凯文勒OK,完成! – user2924019

回答

3

重写如下

Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (item, state) => { 
    if (CallToStop == true) 
     { 
      state.Break(); 
     }   
    internalProcessStart(item); 
}); 

希望这有助于。

+0

谢谢,这是我使用的代码,它很好地工作。谢谢 – user2924019

+1

欢迎您,很高兴帮助。 – RajN

1

我想用这个overload应该工作:

Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (item , state) => 
    { 
     if (/*Stop condition here*/) 
     { 
      state.Break(); 
     }   
     internalProcessStart(item); 
    }); 
0

尝试使用CancellationToken在本example (MSDN)

尝试是这样的:

CancellationTokenSource CTS =新CancellationTokenSource();

 // Use ParallelOptions instance to store the CancellationToken 
     ParallelOptions po = new ParallelOptions(); 
     po.CancellationToken = cts.Token; 
     po.MaxDegreeOfParallelism = Environment.ProcessorCount; 

     try 
     { 
      Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), po, item => { 
       // po.CancellationToken.ThrowIfCancellationRequested(); //1 
       if (CallToStop == true) 
       { 
        //Code here to stop the loop! 
        cts.Cancel(); 
       } 
       if (po.CancellationToken.IsCancellationRequested == false) 
       {   
        internalProcessStart(item); 
       } 
      }); 
     } 
     catch (OperationCanceledException e) 
     { 
      // handle 
     } 
     finally 
     { 
      cts.Dispose(); 
     } 

,而不是直接设置CallToStop = true呼叫cts.Cancel()或者。

或者你可以取消注释// 1,让所有没有完成的thred投掷OperationCanceledException(只有当你停止所有并行线程时,因为CallToStop = true是由错误引起的)。

您甚至可以将cts.Token传入您的internalProcessStart(item,token),并处理如果在内部进程已经运行时取消该做什么。

0

尝试这样的事情。从概念上讲,你需要将loopState传递给你的lambda函数。

Parallel.ForEach<int>(new List<int>(), 
      new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, 
      (val, loopState) => 
      { 
       if (val == 9) //enter your stopcondition here 
       { 
        loopState.Stop(); 
        return; 
       } 
      });