[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] * 目次 [#l24f314e] #contents *概要 [#d9ab14bf] **スレッド [#c79c02e2] スレッドの並列実行はOSが裏で無意識にしてくれていた。 -タイムスライスで細切れ/ラウンドロビンで論理的に並列実行。 -CPUのコア数に応じて、物理的に並列実行。 **タスク [#ae25c1af] async/awaitの登場で、同期型処理と、ほぼ変わらない記述が可能になった。 ***用途 [#kb0ddc1e] -UIスレッドのハングアップを防止するために開発された。 -UIスレッドから、時間のかかるバックグラウンド処理(ネットワーク バインドまたは I/O バインドの処理)を分離する。 -この仕組みは、Webサーバのスレッド枯渇を防ぐ[[非同期コントローラ>ASP.NET MVCの用語#lc319892]]などにも応用されている。 ***タスクの分割 [#gb4b4431] -awaitを切れ目として、プログラマが意識して時間のかかる~ バックグラウンド処理(ネットワーク バインドまたは I/O バインドの処理)を分割する。 --await前の処理はフォアグラウンドで実行される。 --awaitで呼び出す非同期メソッドはバックグラウンドで実行される。 --await後の処理は、コールバックとして実装せずにフォアグラウンドに復帰する。 -昔懐かしい、[[ノンプリエンプティブ・マルチタスク]](Win3.1)なので、スレッドのタイムスライスのような細切れにはならない。 *使い方 [#nf166e6d] -async/awaitの登場で、同期型処理と、ほぼ変わらない記述が可能になった。 -しかし、デバッグの時は非同期で実行されていることを意識する必要がある。 **非同期メソッドの戻り値 [#b43ff41c] ***void型 [#w5cf9ec2] -戻り値としてreturn文を書かない場合 -「イベント・ハンドラかどうか」→ void型 ***Task型 [#t98c2e31] -戻り値としてreturn文を書かない場合 -「待機したいかどうか」→ Task型 ***Task<T>型 [#td2f6464] -非同期処理の結果を受け取りたい場合 -戻り値はTask<T>型だが、returnするのはT型の値 **非同期メソッドの呼び出し [#s278988c] ***Task.Wait()メソッド [#l8b4142b] -Task の実行が完了するまで待機する。 ***await演算子 [#z7b2e8a4] -Task の実行が完了するまで待機する。 --await 非同期メソッド() --await Task.Run() -await演算子の使い方 --非同期メソッドを呼び出すときに、await演算子(後述)を利用する。 --メソッド内でawait演算子(後述)を利用する場合、async修飾子でメソッドを修飾する。 --await演算子は、async修飾子の付くメソッドの中で1つ以上記述できる。 **その他 [#r19de18d] ***Task.WhenAll() [#j18f876f] -Task.WhenAll()メソッドで複数のタスクを待機するタスクを取得する。 -このTaskをTask.Wait()するとTask毎の例外をAggregateException型として取得可能。 *スレッド同期 [#w87411f4] スレッドを使用した処理を記述しないが、分割されたタスクは、 -同一スレッドで動作することも -別スレッドで動作することもある。 このため、一連の処理が(分割されたタスクが)、 -異なるスレッドで実装される保証は無い。 -同じスレッドで実行される保証も無い。 従って、スレッド同期のlock等は無意味。~ 従来のスレッド同期ツールキットは使用不可能。 -lock/mutex/semaphoreはtaskで全て使用禁止 --旧プログラムでmutex使ってる場合に、awaitで追加開発したいときは、SemaphoreSlimに修正が必要 --.NET TIPS:非同期:awaitを含むコードをロックするには?(SemaphoreSlim編)[C#、VB] - @IT~ http://www.atmarkit.co.jp/ait/spv/1411/11/news117.html ---SemaphoreSlim.WaitAsync関数もasync/awaitする。 ---つまり、Semaphoreによるlockさえ、タスクとして分割されて待機/実行される。 -WIN32系同期APIのうち、待機関数のWaitFor[Single|Multi]Objectは例外的に使用可能。 --ThreadPool.RegisterWaitForSingleObject メソッド (System.Threading)~ https://msdn.microsoft.com/ja-jp/library/system.threading.threadpool.registerwaitforsingleobject *参考 [#l0e9a88c] -Tasks are (still) not threads and async is not parallel~ http://blogs.msdn.com/b/benwilli/archive/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel.aspx -c# - Wrapping ManualResetEvent as awaitable task - Stack Overflow~ http://stackoverflow.com/questions/18756354/wrapping-manualresetevent-as-awaitable-task -Insider.NET > 業務アプリInsider > 連載:C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門 - @IT~ http://www.atmarkit.co.jp/ait/subtop/features/dotnet/app/masterasync_index.html