atsukanrockのブログ

Microsoft系技術を中心にぼちぼち更新します

Windows 8.1でのasync voidメソッドに対する例外処理の改善

※この記事はException handling improvements for async void methods in Windows 8.1のざっくり和訳です。

ざっくり言うと

async voidなメソッド内で例外が起こると:

  • Windows 8では‥例外は補足不能。アプリは死ぬ
  • Windows 8.1だと‥Application.UnhandledExceptionイベントハンドラーで例外を補足可能。e.Handled = true;でアプリが死なないようにもできる!

というお話。async voidはベストプラクティス的には禁忌なんですけど、Commandとかイベントハンドラーでめっちゃ使うので、ほっこり嬉しい改善です。

補足すると

ただし「Windows 8.1以降のWindowsストアアプリ開発では、未処理例外が全部Application.UnhandledExceptionイベント飛んでくる」わけではないので注意が必要です。例えば次のようなコード(意味ないけど)があったら飛んできません。

private void ButtonOnClick(object sender, RoutedEventArgs e)
{
    Task.Run(() => { throw new InvalidOperationException(); });
}

ちゃんとawaitしてあげましょう。普通にasync/awaitを使って書いてれば飛んできます。

private async void ButtonOnClick(object sender, RoutedEventArgs e)
{
    await Task.Run(() => { throw new InvalidOperationException(); });
}

ConfigureAwait(false)してても飛んできます。

private async void ButtonOnClick(object sender, RoutedEventArgs e)
{
    await Task.Run(() => { throw new InvalidOperationException(); }).ConfigureAwait(false);
}