14

非同期メソッドがあるとしましょう:

public async Task Do()
{
    await Task.Delay(1000);
}

別のメソッドがブロックDo内のメソッドを呼び出そうとしていますcatch

public async Task DoMore()
{
    try
    {
    }
    catch (Exception)
    {
        await Do(); //compiled error.
    }
}

しかし、このように、コンパイラはawaitinsidecatchの使用を許可していません。そのように使用できなかった背後に何らかの理由がありますか?

4

1 に答える 1

14

アップデート

これは C# 6 でサポートされる予定です。根本的に不可能ではないことが判明し、チームは実装に狂わずにそうする方法を考え出しました :)

元の答え

catch block での使用を妨げるyield returnのと同じ理由であると強く思います。

特に:

まず、try 保護された領域のハンドラーの途中に "goto" することは違法であるという問題がまだ残っています。catch ブロックに入る唯一の方法は、例外をキャッチする「非ローカル goto」を使用することです。したがって、catch ブロックから抜け出すと、次に MoveNext が呼び出されたときに、中断したところの catch ブロックに戻る方法がありません。

第 2 に、スローされてキャッチされた例外は、「空のスロー」構文を使用して再スローできるため、catch ブロックの実行の本質的な部分です。MoveNext の呼び出し間でその状態を保持する方法はありません。

「yield」を「await」に置き換えると、答えが得られると思います。

ほとんどの場合、これを行うのは奇妙に思えますが、通常は、ブロックの後で待機するようにコードをかなり簡単に書き直すことができるはずcatchです (もちろん、何かを待機してからスローしようとしている場合を除く)。その場合、それは少し苦痛になるでしょう、私は認めます...

于 2012-10-14T06:46:32.223 に答える