【C#.NET】非同期処理(async)でハマった話

asyncを使った非同期処理でそこそこハマってしまったので、結果から言えば大した話ではないのだけど自戒を込めてメモ。

以下のようなコードがありました。

private async void message()
{
    MessageBox.Show("メッセージ1");

    messageAsync();

    MessageBox.Show("メッセージ3");
}

private async void messageAsync()
    {
    await Task.Run(() =>
    {
        System.Threading.Thread.Sleep(2000);

        MessageBox.Show("メッセージ2");
    });
}

本来は
メッセージ1

メッセージ2

メッセージ3

と表示して欲しいのですが、実際には以下のような動きとなります。

メッセージ1

メッセージ3

メッセージ2

この場合の正しいコードは以下。

private async void message()
{
    MessageBox.Show("メッセージ1");

    await messageAsync();

    MessageBox.Show("メッセージ3");
}

private async Task messageAsync()
{
    await Task.Run(() =>
    {
        System.Threading.Thread.Sleep(2000);

        MessageBox.Show("メッセージ2");
    });
}

非同期処理を行うメソッド側でTaskを戻り値とし、呼び出し元はきちんと待ち合わせしてあげましょうと。
これをやらないと単なる投げっぱなしのスレッドになってしまいますよ・・・というお話でした。。