Skip to content

Instantly share code, notes, and snippets.

@neuecc
Last active July 23, 2017 14:28
Show Gist options
  • Save neuecc/da94a473861ddfb98956 to your computer and use it in GitHub Desktop.
Save neuecc/da94a473861ddfb98956 to your computer and use it in GitHub Desktop.
async void is 危険
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void button_Click(object sender, EventArgs e)
{
MyVoidAsync1();
}
// このタイミングでは、このメソッドで発生する例外は呼び出し元のSynchronizationContextに送られる
// つまりこの中ではConfigureAwait(false)しようが何しようが、例外はDispatcherに送られるので安全
async void MyVoidAsync1()
{
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
MyVoidAsync2();
}
// ↑のメソッドの中でSynchronizationContextを失っている
// つまりこの中で発生した例外はnullにPOSTすることになり誰も捉えられない
// その時、TaskScheduler.Unobserved行き、と思いきや、これは
// CurrentDomain.UnhandledExceptionにすっ飛んでいくので、アプリごと殺す
async void MyVoidAsync2()
{
await Task.FromResult(0);
throw new Exception("アプリごとしぬ");
}
}
@neuecc
Copy link
Author

neuecc commented Dec 11, 2014

CurrentDomain.UnhandledExceptionにすっ飛ぶ理由ですが、
async voidとasync Taskでは生成されるコードが違うからです。

その辺の細かい話はいつかそのうちブログに書きましょう……。

@neuecc
Copy link
Author

neuecc commented Dec 11, 2014

ちなみにWPFだけじゃなくてWinFormでもASP.NETでも叩き落とせる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment