C#での非同期プログラミング

C#でのasync&awaitとTaskの使い方と非同期の考え方をわかりやすく解説#5

async await編

async awaitとは何か?

async&awaitとは.NETFramework4.5で追加された機能で,非同期処理をより同期的に記述できる機能です。

async awaitを使うとどんな良いことがあるのか?

async&awaitは前述のTaskと組み合わせることで同期プログラミングをしているような書き方で非同期プログラミングができます。.NETFramework4.5以降の開発環境でプログラミングしている場合は積極的にasync&awaitを使用しましょう。

async awaitを使わないとどんな悪いことがあるのか?

async&awaitを使わない場合は,UIスレッドに戻す記述を前述のTaskで紹介したContinueWithを使用して記述する必要があるので,async&awaitに比べると可読性は下がります。

async awaitの使い方

AsyncAwaitButton_Clickイベント

まず3行目の「var dtos = await Task.Run(() => GetDataAsync());」ですが,Task.Run以降の部分はTaskの時と同じです。Taskの例にあったContinueWith以降の記述がなくなっています。Task.Runの直前にawaitというキーワードがあります。このキーワードがあるとTask.Runで実行している非同期処理の完了を待ってから,それ以降の処理がUIスレッド上で行われるようになります。

この例で言うと,非同期処理GetDataAsyncの処理が終わってから戻り値がdtosにセットされるタイミング以降はボタンクリック時に動作するUIスレッドに戻ってきているので,何の記述もなく普通に「dataGridView1.DataSource = dtos; 」を記述することができます。これはまさに同期的プログラミングの例と同じになります。
※記述は一行にして「dataGridView1.DataSource = await Task.Run(() => GetDataAsync());」でも問題ありません。

1行目のasyncのキーワード決まりごとです。asyncキーワードで修飾されていないメソッドではawaitキーワードは使用できない決まりになっています。awaitを使う場合は必ずasyncキーワードが必要になります。

GetDataAsyncメソッド

GetDataAsyncはTaskの例のときと同じです。async&awaitはTaskと組み合わせて使っているので,このあたりは同じです。

async&awaitの書き方まとめ

TaskのときはContinueWithで書かなければいけなかったUIスレッド上の処理が,一切不要になったため,非同期処理の書き方としては,完成されたものになっていると思います。

まとめ

.NETFramework4.0より前の場合は極力ThreadPoolをしようし,監視処理などスレッドを占有する場合のみThreadクラスを使用する※今回は解説しませんでしたが,監視処理をするのであればSystem.Threading.Timerが良いでしょう。

.NETFramework4.0を使うならThreadPoolの代わりにTaskを使う。
.NETFramework4.5以降を使うならTaskとasync&awaitを組み合わせて使う。

非同期プログラミング