2016-09-29 226 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; 
       } 
      });