Open棟梁Project - マイクロソフト系技術情報 Wiki
目次 †
概要 †
スレッド †
スレッドの並列実行はOSが裏で無意識にしてくれていた。
- タイムスライスで細切れ/ラウンドロビンで論理的に並列実行。
- CPUのコア数に応じて、物理的に並列実行。
タスク †
async/awaitの登場で、同期型処理と、ほぼ変わらない記述が可能になった。
用途 †
- UIスレッドのハングアップを防止するために開発された。
- UIスレッドから、時間のかかるバックグラウンド処理(ネットワーク バインドまたは I/O バインドの処理)を分離する。
- この仕組みは、Webサーバのスレッド枯渇を防ぐ非同期コントローラなどにも応用されている。
タスクの分割 †
- awaitを切れ目として、プログラマが意識して時間のかかる
バックグラウンド処理(ネットワーク バインドまたは I/O バインドの処理)を分割する。
- await前の処理はフォアグラウンドで実行される。
- awaitで呼び出す非同期メソッドはバックグラウンドで実行される。
- await後の処理は、コールバックとして実装せずにフォアグラウンドに復帰する。
使い方 †
- async/awaitの登場で、同期型処理と、ほぼ変わらない記述が可能になった。
- しかし、デバッグの時は非同期で実行されていることを意識する必要がある。
非同期メソッドの戻り値 †
void型 †
- 戻り値としてreturn文を書かない場合
- 「イベント・ハンドラかどうか」→ void型
Task型 †
- 戻り値としてreturn文を書かない場合
- 「待機したいかどうか」→ Task型
Task<T>型 †
- 非同期処理の結果を受け取りたい場合
- 戻り値はTask<T>型だが、returnするのはT型の値
非同期メソッドの呼び出し †
Task.Wait()メソッド †
await演算子 †
- Task の実行が完了するまで待機する。
- await 非同期メソッド()
- await Task.Run()
- await演算子の使い方
- 非同期メソッドを呼び出すときに、await演算子(後述)を利用する。
- メソッド内でawait演算子(後述)を利用する場合、async修飾子でメソッドを修飾する。
- await演算子は、async修飾子の付くメソッドの中で1つ以上記述できる。
その他 †
Task.WhenAll?() †
- Task.WhenAll?()メソッドで複数のタスクを待機するタスクを取得する。
- このTaskをTask.Wait()するとTask毎の例外をAggregateException?型として取得可能。
スレッド同期 †
スレッドを使用した処理を記述しないが、分割されたタスクは、
- 同一スレッドで動作することも
- 別スレッドで動作することもある。
このため、一連の処理が(分割されたタスクが)、
- 異なるスレッドで実装される保証は無い。
- 同じスレッドで実行される保証も無い。
従って、スレッド同期のlock等は無意味。
従来のスレッド同期ツールキットは使用不可能。
- lock/mutex/semaphoreはtaskで全て使用禁止
- WIN32系同期APIのうち、待機関数のWaitFor?[Single|Multi]Objectは例外的に使用可能。
参考 †