10

を使用して、非同期タスクによってスローされる可能性のある例外をラップしようとしていますContinueWith()。継続アクションからスローしただけでは動作しているように見えますが、デバッガーは例外が処理されていないと主張しています。何か間違ったことをしていますか、それとも Visual Studio の問題ですか? これを行うためのよりクリーンな方法、または最終的に処理された例外で停止するデバッガーを回避する方法はありますか?

以下のテストは成功し、「期待どおりにラップされた例外がキャッチされました」と出力されますが、デバッグすると、throw new CustomException「ユーザーコードによって処理されていない」という行が表示されます。

var task = DoWorkAsync().ContinueWith(t => {
    throw new CustomException("Wrapped", t.Exception.InnerException);  // Debugger reports this unhandled
}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);

try {
    task.Wait();
    Assert.Fail("Expected work to fail");
} catch (AggregateException ag) {
    if (!(ag.InnerException is CustomException))
        throw;
}
Console.WriteLine("Caught wrapped exception as expected");
4

2 に答える 2

12

"Just My Code" が有効になっている場合、例外をスローする行で Visual Studio が中断し、"例外はユーザー コードによって処理されません" というエラー メッセージが表示されることがあります。このエラーは無害です。F5 キーを押して続行し、これらの例で示されている例外処理の動作を確認できます。Visual Studio が最初のエラーで中断しないようにするには、[ツール]、[オプション]、[デバッグ]、[全般] の下にある [マイ コードのみ] チェックボックスをオフにします。

http://msdn.microsoft.com/en-us/library/dd997415.aspxから

于 2012-12-19T22:17:12.290 に答える
7

継続で例外を「ラップ」しているようには見えません。継続で例外をスローしているようです。DoWorkAsync が例外をスローする可能性がある場合、次のように継続でそれを「ラップ」します。

DoWorkAsync().ContinueWith(t=>{
 Console.WriteLine("Error occurred: " + t.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);

または、非同期メソッドの外で例外を「処理」する場合は、次のようにします。

var task = DoWorkAsync();

task.Wait();
if(task.Exception != null)
{
  Console.WriteLine("Error occurred: " + task.Exception);
}

スローされた例外を変換したい場合は、次のようにすることができます。

var task = DoWorkAsync().ContinueWith(t=>{
 if(t.Exception.InnerExceptions[0].GetType() == typeof(TimeoutException))
 {
     throw new BackoffException(t.Exception.InnerExceptions[0]);
 }
}, TaskContinuationOptions.OnlyOnFaulted);

そして、次のように処理できますBackoffException

if(task.IsFaulted)
{
   Console.WriteLine(task.Exception.InnerExceptions[0]);
   // TODO: check what type and do something other than WriteLine.
}
于 2012-07-26T21:33:19.673 に答える