2012-09-24 79 views
7

我試圖允許取消Parallel.ForEach循環。根據this MSDN article,這是可能的,我正在遵循他們的編碼。未處理的OperationCanceledException從Parallel.ForEach拋出時

// Tokens for cancellation 
ParallelOptions po = new ParallelOptions(); 
po.CancellationToken = cts.Token; 

try 
{ 
    Parallel.ForEach(queries, po, (currentQuery) => 
    { 
     // Execute query 
     ExecuteQuery(currentQuery); 

     // Throw exception if cancelled 
     po.CancellationToken.ThrowIfCancellationRequested(); // *** 
    }); 
} 
catch (OperationCanceledException cancelException) 
{ 
    Console.WriteLine(cancelException.Message); 
} 

然而,當我打電話cts.Cancel();從用戶可訪問的功能,上線的應用程序崩潰標有星號上面的錯誤:

System.OperationCanceledException was unhandled by user code 
    Message=The operation was canceled. 
    Source=mscorlib 
    StackTrace: 
    at System.Threading.CancellationToken.ThrowIfCancellationRequested() 
    at CraigslistReader.SearchObject.<>c__DisplayClass7.<bw_DoWork>b__5(Query currentQuery) in {PATH}:line 286 
    at System.Threading.Tasks.Parallel.<>c__DisplayClass2d`2.<ForEachWorker>b__23(Int32 i) 
    at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c() 
InnerException: 

我有異常處理程序就在那裏,所以我不明白這次事故。有任何想法嗎?

+0

我沒有看到你描述的問題,'catch'對我來說工作正常。你能發佈一個完整但短的代碼來顯示你的問題嗎? – svick

+0

我不認爲該應用程序崩潰,至少沒有這個例外。要麼你的應用程序沒有崩潰(你怎麼知道它崩潰?),或者這不是最後發生的異常。 – usr

+0

@usr是的,你是對的。我在調試器中運行它,當我看到異常停止運行時,我認爲這是一個異常,會導致應用程序崩潰。我不知道一些例外不是崩潰的。 – Doug

回答

2

問題是po.CancellationToken.ThrowIfCancellationRequested();顯式拋出一個未處理的異常。異常處理程序可能在調用Parrallel.ForEach()附近,但異常不在lambda表達式內處理。在lambda表達式中刪除該行或添加一個異常處理程序,它應該可以工作。

查看Cancelling a Task is throwing an exception瞭解更多信息。

+0

那麼,你說MSDN示例是錯誤的? – svick

+0

@svick可能。看看我連接的答案,並嘗試它的建議。如果它起作用,它就會起作用。 – akton

+0

@akton:我嘗試將try/catch放在lamba表達式中,它仍然導致運行時錯誤。 – Doug

相關問題