7

Parallel.ForEachループのキャンセルを許可しようとしています。このMSDNの記事によると、それは可能であり、私は彼らのコーディングに従っています。

// 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: 

そこに例外ハンドラがあるので、クラッシュがわかりません。何か案は?

4

1 に答える 1

2

問題は、po.CancellationToken.ThrowIfCancellationRequested();未処理の例外を明示的にスローしていることです。例外ハンドラーはParrallel.ForEach()呼び出しの周囲にある可能性がありますが、例外はラムダ式内で処理されません。行を削除するか、ラムダ式内に例外ハンドラーを追加すると、機能するはずです。

詳細については、「タスクのキャンセルが例外をスローする」を参照してください。

于 2012-09-24T00:20:37.227 に答える