xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

非同期メソッド入門 (3) - 任意の記述場所

async修飾子やawait演算子は、前回紹介したサンプルのような利用箇所に留まりません。適用可能箇所は以下の通りです。

キーワード 適用できる箇所 適用できない箇所
async修飾子 通常のメソッド
ラムダ式
匿名メソッド
コンストラクタ
デストラクタ
await演算子 式が書ける箇所ならどこでも lockステートメント
catch句
finally句

なので、例えば次のような記述も可能です。

Action action = async () =>
{
    foreach (var item in await GetEnumerableAsync())
        Console.WriteLine(item);
};
action();
DoSomething(async () =>
{
    while (await CanExecuteAsync())
        await Task.Run(() => Thread.Sleep(3000));
});

実際の活用場面はさておき、非同期処理をそこかしこに違和感なく書くことができる、ということだけでも覚えておくと幅が広がりそうです。

非同期メソッドを適用できない箇所

しかしながら記述箇所に制約がないわけではありません。先の表にも簡単に記載しましたが、次のような箇所には非同期メソッドを適用できませんので注意が必要です。(もしかしたら他にもあるかもしれません)

class Hoge
{
    public async Hoge()         //--- NG
    {
        await Task.Delay(1000); //--- NG
    }

    async ~Hoge()               //--- NG
    {
        await Task.Delay(1000); //--- NG
    }

    public async Task DoSomethingAsync()
    {
        try
        {
            lock (this)
            {
                await Task.Delay(1000); //--- NG
            }
        }
        catch
        {
            await Task.Delay(1000); //--- NG
        }
        finally
        {
            await Task.Delay(1000); //--- NG
        }
    }
}