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 } } }