進化して、最近ではBackgroundWorkerの代わりにTaskというものが登場してきていますね。これは、BackgroundWorkerよりもコーディング量が少なくて同じようなことが実現できるので便利なのですが、巷の説明ブログを読んでいると、なんだか間違った解説をもっともらしく発表している残念なサイトが多く、実際の使用を想定したサンプルも少ないような気がしたので、ここでサンプルとともにまとめておきたいと思います。サンプルプログラム(スケルトン)まずは、プログラム全体を見られるようにスケルトンの状態でソースを公開します。このプログラムは、Windowsのあるフォームのソースです。フォームロードイベント(FormTest_Load)が起点となり、フォームが画面に表示される際に、サーバなどからデータを取ってきて画面に表示するようなことを想定しています。msg){Console.WriteLine(msg);}}}プログラムの流れプログラムの流れを見ていくと、以下のようになります。フォームロードイベントが発行されFormTest_Load関数が呼び出されます。FormTest_Load関数の中ですぐに時間がかかる処理(バックグランド処理)を呼び出す役目の関数(MyTestFunction)が呼び出されます。MyTestFunctionは、実際に処理に時間がかかる関数(MyBackgroundTestFunction)をバックグランド処理として実行します。個別の処理を見ていきたいと思います。MyTestFunction()」がこれに相当します。」句を使用しているため、このawait句がある関数の宣言では「async」を付ける必要があります。フォームロードイベントの関数の中で直接MyTestFunction関数の内容を書きたい場合は、フォームロードイベントハンドラの関数の定義の部分で「async」を宣言します。Progress<string>(onProgressChanged);バックグランドで実行中の処理から処理の状況を報告するためのしくみがProgressです。ここではstring型の引数を1つ取るプログレス用の関数を定義しておきます。引数は通常の関数と同じで、いくつでも設定できます。MyBackgroundTestFunction(progress));これがバックグランドプロセスを起動している部分です。このバックグランドプロセスはstring型の戻り値を返し、引数としてProgress型のデータを1つ定義しています。引数はいくつでも追加できます。task;この部分に到達すると、処理が一旦戻ります。Returnで関数から戻るようなイメージです。FormTest_Loadのようにasyncの関数を呼び出している関数のようば場合注意が必要ですFormTest_Loadの中でMyTestFunctionを呼び出した後に処理を入れないようにします。しないとawait句で一時的に戻ってきたときに、その処理が実行サれてしまうからです。await句の動作は以下のようになります。Task.Runによってバックグランドプロセスが起動されます(青の線)。次に、呼び出し元のほうでは、await句によってReturnと同じ動作をし、MyTestFunction関数から抜け、さらにFormTest_Loadからも抜けて、メッセージループへ戻ります(赤い線)。バックグランドの処理(MyBackgroundTestFunction)が終了すると、await句の次の行から処理が再開されます(緑の線)。resultには、バックグランド処理(MyBackgroundTestFunction)のreturn句で返された情報が入ります。これは必ずしもstring型である必要はなく、自分の好きデータ型を指定できますので、処理後の情報を渡すときなどに使えます。動作確認では、先程のサンプルプログラムの様々なポイントにログを挿入して、実行結果を見てみたいと思います。FormTest_Load関数では、async関数の「MyTestFunction」が呼び出され、Route(2)のログが出力されています。ここでバックグランド処理が起動されています。Route(3)では、await句が呼び出されます。そのため、呼び出し元の処理はReturnされ、MyTestFunction関数から上位の関数FormTest_Loadへ戻ったために、ここでRoute(1)のログが出ています。バックグランド処理側(ThreadId(3)側)では、処理中のログの出力をするとともに、プログレス報告が呼び出し元に報告されています。Route(4)のログは、バックグランド処理の結果情報を受け取って表示しています。