非同期実行(別スレッドで実行)する処理と、その処理の完了後に実行される処理を、同期実行に似たかたちのコードで書くためのキーワード。
asyncは、内部でawaitを使う関数であることを示すためのキーワードで、機能は無い。
awaitは、その直後に「Taskオブジェクトを戻す式」を置く。
「Taskオブジェクトを戻す式」が実行された時点でasync関数の動作は一時ストップする。「Taskオブジェクトを戻す式」のTaskの処理が完了したら、async関数の動作が再開する。
private async void AsyncRun() { MessageBox.Show("start"); foreach (var i in Enumerable.Range(0, 5)) { await Task.Delay(1000); // Task.Run(() => System.Threading.Thread.Sleep(1000)) と同じ MessageBox.Show(i.ToString()); } MessageBox.Show("end"); }
asyncキーワードの書かれた関数f は ジェネレータを返すyield関数 になり、await直後の式のpromeseを戻して、promise.thenでfを継続実行させる。
(await x → yield x.then(arguments.callee()).resolve() に展開)
という感じで理解できる概念。
javascript(ES2016)にもほぼ完全に同じ機能がある。
ただしawaitの後に続く関数はTaskではなくpromiseを戻すべきであるところが違う。
http://www.atmarkit.co.jp/ait/articles/1601/22/news038_2.html
function doLongTimeTask(n, msg) { return new Promise((resolve, reject) => { setTimeout(() => resolve('resolved: ' + msg), n); }); } async function doLongTimeTaskAsync() { var result; result = await doLongTimeTask(1000, 'task1'); console.log(result); result = await doLongTimeTask(1000, 'task2'); console.log(result); result = await doLongTimeTask(1000, 'task3'); console.log(result); }