「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>プログラミング]]
-[[戻る>その他、開発の色々]]

* 目次 [#lc8e4fa8]
#contents

*概要 [#u945caf6]
非同期処理の実装方式について。

*非同期処理の実装史 [#z67fe1ac]
**1. Thread、ThreadPool [#c79c02e2]
従来の、マルチスレッド・プログラミング。
*詳細 [#wfdea936]

-スレッドの並列実行はOSが裏で無意識にしてくれていた。
--タイムスライスで細切れ/ラウンドロビンで論理的に並列実行。
--CPUのコア数に応じて、物理的に並列実行。
**非同期処理の定義 [#x26ee802]
-一般的に、非同期処理と言うと、~
同期処理(オンライン)との対比になり、~
同期処理(オンライン)オンラインとの待ち合わせをする。

-しかし、以下の処理は意識的に実装する必要があった。
--非同期処理をスレッド関数として分離して実装する。
--スレッド関数を作成したワーカースレッドに渡す。
--スレッド関数の結果をメインスレッドで待ち合わせる。
-同期処理(オンライン)と待ち合わせをしない場合は、~
同期処理(オンライン)から、
--別途スレッドを生成し、そのワーカースレッドで処理させたり、
--キューにキューイングして、バッチで処理させたり、

**2. APM、EAP ([[Control.Invoke、.BeginInvoke]]) [#x24ad95f]
-「Windowsメッセージングキュー([[Control.Invoke、.BeginInvoke]])」による方式。
>することになるが、対比するものが無いため非同期か?と言うと、~
単なるバッチ処理やマルチスレッド処理、若しくは並列処理と言った方がイイかも知れない。

--APM(Asynchronous Programming Model)~
[[Control.Invoke>http://www.atmarkit.co.jp/ait/articles/0506/17/news111.html]]
--EAP(Event-based Asynchronous Pattern)~
[[BackgroundWorker>http://www.atmarkit.co.jp/fdotnet/dotnettips/436bgworker/bgworker.html]]
**非同期処理の実装史 [#z67fe1ac]
-プリミティブな実装を隠蔽する方向で進化しているが弊害もある。
-例 : https://twitter.com/neuecc/status/1011512880770965504

-この非同期処理方式では、
***1. Thread、ThreadPool [#c79c02e2]
-概要
--従来の(プリミティブな)、マルチスレッド・プログラミング。

--Foregroundスレッド(UIスレッド)からBackgroundスレッドを使用して非同期処理を実行し、
--非同期処理の実行結果をUIスレッドを使用して画面に反映させる事ができる。
-詳細
--スレッドの並列実行はOSが裏で無意識にしてくれていた。
---タイムスライスで細切れ/ラウンドロビンで論理的に並列実行。
---CPUのコア数に応じて、物理的に並列実行。

-上記をラップするライブラリ
--[[BackgroundWorker クラス>https://msdn.microsoft.com/ja-jp/library/system.componentmodel.backgroundworker.aspx]]
---方法 : バックグラウンド ワーカーを使用する~
http://www.atmarkit.co.jp/fdotnet/dotnettips/436bgworker/bgworker.html
---BackgroundWorkerクラスを使用して進行状況ダイアログを作成する: .NET Tips: C#, VB.NET~
http://dobon.net/vb/dotnet/programing/progressdialogbw.html
--しかし、以下の処理は意識的に実装する必要があった。
---非同期処理をスレッド関数として分離して実装する。
---スレッド関数を作成したワーカースレッドに渡す。
---(必要に応じて)ワーカースレッドの結果をメインスレッドで待ち合わせる。

--Open棟梁の「[[非同期呼出フレームワーク>https://opentouryo.osscons.jp/index.php?%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%91%BC%E5%87%BA%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF]]」。
-参考~
・・・

**3. TAP ([[async/await]]) [#ae25c1af]
[[async/await]]は、TAP(Task-based Asynchronous Pattern)の方式で実装されている。
***2. APM (Beginメソッド, Endメソッド) [#j57ffa0c]
-概要
--「[[前述のThread、ThreadPool>#c79c02e2]]」から非同期を意識したAPIを設計に変更した程度。
--代表的なメソッド
---Streamクラスの、BeginRead および EndRead メソッド
---WebRequestクラスの、BeginGetResponse および EndGetResponse メソッド

[[async/await]]は、
-メッセージ(番号)のような制約のある単純固定長値のキューではなく、~
実行コードの任意のコード断片そのものをキュー(同期コンテキスト)を使用して繋いでいる。
-.NET 3.5用のasync/await互換NuGetパッケージでは、~
.NET 4のTask互換クラスを、内部をBeginInvoke等で実装して、async/awaitを使えるようにしていた。
-詳細
--Beginメソッドに Endメソッドのdelegate(≒callback)を渡す。
--同期方法はクラスの実装に依る。

***概要 [#q74e6e48]
-[[async/await]]の登場で、マルチスレッド処理として実装しなくても、~
非同期処理を同期型処理と、ほぼ変わらない記述で容易に実装可能になった。
-参考
--非同期プログラミング モデル (APM) | Microsoft Docs~
https://docs.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm

-awaitの意味は、スレッドを止めずノンブロッキングで非同期から同期に復帰するという意味らしい。
***3. EAP ([[Control.Invoke、.BeginInvoke]]) [#x24ad95f]
-概要
--裏で、[[ウィンドウ メッセージ]]を使用した非同期処理方式。
--[[SwingのSwingWorker>https://stackoverflow.com/questions/281855/what-is-the-rationale-of-swingworker]]などを見てもGUIの非同期は、ほぼ同じ様な仕組みになるもよう。~

>実際、[[async/await]]はそういう動きをする。
-詳細
--[[前述のAPM>#j57ffa0c]]と同様に、Invokeメソッドにdelegate(≒callback)を渡す。
--同期方法は[[ウィンドウ メッセージ]]に依る。

--スレッドやWindowsメッセージングキューでTask化される。~
昔懐かしい、[[ノンプリエンプティブ・マルチタスク]](Win3.1)のようなイメージ。
-参考
--[[Control.Invoke、.BeginInvoke]]を参照。
--イベント ベースの非同期パターン (EAP) | Microsoft Docs~
https://docs.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-eap

--しかし、その実態はとても複雑、詳しくは[[コチラ>#nc344611]]を参照。
---内部がどう動いているか詳しく把握せんとシステムは安定しない、
---中身をシッカリ理解して使用している人が少ないので注意。
***4. Future/Promise [#mfb931c1]
-概要
--C#には無いが、[[JavaScriptのPromise>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?Promise%20%28JavaScript%29]]が有名。
--その他にも、JavaVM(Java、Scala)、C++などで標準ライブラリが提供されている模様。

***余談? [#ef267401]
[[async/await]]の夫々の意味。
-詳細
--非同期のcallbackを、delegateを引数に取るmethod chainに、匿名delegateで実装していく感じ。
--このコーディング・スタイルにより、あまりcallbackっぽく見えない同期に近いコーディングが可能。
--しかし、非同期処理の結果から、また非同期を呼び出すようなコードは上手く書けない。

-async修飾子~
asyncは、呼び出し元と同じ同期コンテキストで実行されることを示す。
-参考
--言語によってちょっと違うFuture/Promiseをまとめてみた
---(1): https://qiita.com/reki2000/items/6acf94a07dee8d26a744
---(2): https://qiita.com/reki2000/items/c9739a392632a7cb94b0
---(3): https://qiita.com/reki2000/items/13f94745c6db80a586a8

-await演算子~
asyncをawaitすると、スレッドを止めずに同期コンテキストで同期する。
***5. TAP ([[async/await]]) [#ae25c1af]
-概要
--[[async/await]]で、同期呼び出し的に非同期処理を記述可能になった。
--斬新な仕組みのため、無批判で浸透したが、昨今、振り返りフェーズにある気がする。

この動作は想像し難いが、具体的には、
-同じ同期コンテキスト(Windowsメッセージングキュー)に
-コールバックを順番に並べる(Control.BeginInvoke()的な)。
-詳細
--同期方法は[[同期コンテキスト>async/await#je52c46b]]に依存する。

というイメージ。
-参考
--[[async/await]]を参照。
--タスク ベースの非同期パターン (TAP) | Microsoft Docs~
https://docs.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap

-・・・結局、APM、EAPと同じ技術(同期コンテキスト)を使っている。
***6. [[Reactive Extensions(Rx)]] [#lf9e0bc2]
-概要
--[[Silverlight Toolkitに"System.Reactive.dll"が同梱>Reactive Extensions(Rx)#pbb87a6d]]されたのをきっかけに始まり各言語に広まった。
--Observer パターンを実装するフレームワークで、イベントや非同期処理をLINQっぽく扱える。

-なお、同期コンテキストの種類によって、動きも異なる。
--同期コンテキストはキュー的なもので実装されている。~
例えば、前述の、
---Windowsメッセージングキュー、
---ThreadPool
---I/O 完了ポート
---, etc.
-詳細
--「状態変化を検知して非同期イベントを発火」のようなライブラリなので、~
業務系にはミスマッチと思われる。ゲーム業界などでは使われている模様。
--最近の、非同期呼出というコンテキスト上では、[[async/await>#ae25c1af]]が優勢である模様。

--なので、言葉尻だけで動作を想像し難く、~
[[利用の際は注意が必要になってくる>async/await#c3aa7761]]。
-参考
--[[Reactive Extensions(Rx)]]を参照

**4. [[Reactive Extensions(Rx)]] [#lf9e0bc2]
*参考 [#b6ba428d]
-非同期プログラミングのパターン | Microsoft Docs~
https://docs.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/

*参考 [#b6ba428d]
-.NET開発における非同期処理の基礎と歴史 - @IT~
http://www.atmarkit.co.jp/fdotnet/chushin/masterasync_01/masterasync_01_02.html

-ハッシュタグ #Unity非同期完全に理解した~
https://twitter.com/hashtag/Unity%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%AE%8C%E5%85%A8%E3%81%AB%E7%90%86%E8%A7%A3%E3%81%97%E3%81%9F?src=hash

**SlideShare [#j4d6b3bb]
-C#次世代非同期処理概観 - Task vs Reactive Extensions~
http://www.slideshare.net/neuecc/asynchronous-rx-andtask
-async/await のしくみ~
https://www.slideshare.net/ufcpp/asyncawait-114647813

**[[Rx>#lf9e0bc2]] + [[async Task>#ae25c1af]] [#nefc1c9b]
-neue cc - Reactive Extensions + asyncによるC#5.0の非同期処理~
http://neue.cc/2012/07/11_377.html
--非同期メソッド入門 (11) - Rxとの相互運用 - xin9le.net~
http://blog.xin9le.net/entry/2012/12/11/005445
--Curing Your Event Processing Blues with Reactive Extensions (Rx) | TechEd Europe 2012 | Channel 9~
https://channel9.msdn.com/Events/TechEd/Europe/2012/DEV413

----
Tags: [[:プログラミング]], [[:その他、開発の色々]], [[:.NET開発]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS