3

コードで発生した問題から始めて、問題を再現するためにこのシンプルなアプリを作成しました。

private async void button1_Click(object sender, EventArgs e)
{
    Task task = Task.Run(() =>
    {
        TestWork();
    });
    try
    {
        await task;
        MessageBox.Show("Exception uncaught!");
    }
    catch (Exception) { MessageBox.Show("Exception caught!"); }
}

private async void button2_Click(object sender, EventArgs e)
{
    Task task = TestWork();
    try
    {
        await task;
        MessageBox.Show("Exception uncaught!");
    }
    catch (Exception) { MessageBox.Show("Exception caught!"); }
}

private async Task TestWork()
{
    throw new Exception();
}

のコードbutton1_Clickは例外をキャッチしません。TestWorkこれは、 asyncメソッドを待っていないためであることを確認しました。実際、Visual Studioから、メソッドを待っていないことを通知する警告メッセージが表示されます。ただし、ソリューションがコンパイルされ、async / awaitを広範囲に使用すると、コード内のどこかでこれが発生する可能性があるのではないかと心配しています。それで、理由を説明してください、そして、peraphsはそれを避けるためにいくつかの黄金のルールを与えますか?

PS:button1_Click私が書いたコードで次の場合に機能します:

Task task = Task.Run(async () =>
{
    await TestWork();
});
4

1 に答える 1

2

最初の実装では、によって返されbutton1_Clickた結果を無視しています。TaskTestWork

変更されたバージョンではawait、例外をチェックし、キャッチできるようにそれを伝播します。

実際、表示されているコンパイラの警告は通常重要です。TestWork実際に別のスレッドで何かを実行した場合Task、最初の実装のラッパーは完了するのを待たないためTestWork、開始するとすぐに自動的に完了しTestWorkます。

このように書くと、より明確になります。

Task task = Task.Run( () =>
    {
        Task t = TestWork();
        // ignore t
    }
);
于 2012-06-05T10:25:42.073 に答える