4/5に、わんくま同盟 東京勉強会 #89に行ってきました。
わんくま同盟
わんくま同盟 東京勉強会 #89
全4回に分けて、セッションの内容を紹介します。今回は第3回です。
3つ目のセッションは、荒井省三さんの「async/awaitの基本」でした。
非同期プログラミングとは
- 演算子というよりオペレーターである
- メインスレッドと異なるスレッドを利用ということ
- 処理結果をほしいかどうかは使い方しだい
- メインスレッドが終わるとプロセスが終わるので、非同期スレッドも終わる
非同期を使う理由
- 目的は応答なしを防止したい
- ForkしてJoinする(分岐して結果を集める)
- ある一定数以上は分岐できない
- アムダールの法則
非同期の手法
- スレッド
- スレッドプール
- OSが勝手な順番で実行する
- Dispacher.BeginInvoke
- キューを持っていることがスレッドプールとは違う
- 順番どおりに実行
- プライオリティを変えられる
非同期の課題
- スレッドに入れたものの処理順序をどうやって保証したいか
- メインのスレッドとどうやって同期するか
- イベントを使うのが王道
- それ以外の方法はマシン依存になってしまう
- 開発機で動作しても本番機で動作するかわからない
- スレッドで処理した結果の受け取り
- デッドロックの可能性がある
- メモリアライメントを意識する必要がある
- イベント引数をつかうのが安全
- 値渡しだから
非同期プログラミングモデル(APM)
- Begin~、End~を使ったコールバックモデル
- すべての根本、基本
- でも書くのは面倒くさい
イベントベース非同期パターン(EAP)
- APMをイベントでラップした非同期プログラミングパターン
タスクベース非同期パターン(TAP)
- Taskオブジェクトでラップしたもの
PLINQ
- データ並列に使える
- データを勝手にパーティショニングして、スレッドに振り分けてくれる
- 例:URlをコレクションにいれておくと、並列にリクエストを送れる
async/awaitパターン
- async/awaitオペレーターを使う
- asyncを書くと非同期メソッドになる
- awaitを書くと結果を受け取れる
デモ
- 同期処理
- 処理が終わるまでUIが固まる
- 単純にワーカースレッドに切り出す
- 結果を受け取れない
- ワーカースレッドが終わった後Joinする
- 結果を待つためにJoinするので、応答なしの瞬間が発生する
- スレッドプール使用
- 応答なしにならない
- スレッドプールが終わったかわからない
- 結果を受け取れない
- async
- 結果を順番に取得できる
- C#コンパイラがコードを生成するためのもの
- Refrectorで自動生成されるソースコードを見てみる
- d__0とは、IAsyncStateMashineを実装する構造体
- AsyncVoidMethodddBuilderを呼び出す
- SyncronizationContextをprivateのフィールドで持っている
- UIスレッドと同期するため
- awaitを複数書くと、IAsyncStateMashineを実装する構造体が複数作成される
- 戻り値にはTask<T>以外は使わないこと
非同期メソッドの基本原則
- Immutableなメソッドが基本
- 引数によってのみ戻り値が変わる
- 副作用がない
同期メソッドとして扱う
- Task.GetAwaiter.GetResults
- ストアアプリ
- IAsyncAction、IAsyncOperation、IAsyncXXXWithProgress<T>、
- TaskAwaiterを使えば、Completedイベントで結果を受け取れる
- 例:コンストラクタ(async,awaitは使えない)
まとめ
- awaitを2つ書いた瞬間に、はまる可能性が発生する
- awaitを複数使う場合、Task.ConfigureAwaitでSyncronizationContextを無効にできる
- ただし自分で結果を受け取るコードをかかなければならない
- async,awaitは非同期処理の課題を解決してはくれない
- Immutableにすることを心掛ける
- メモリアライメントに注意しないと、デッドロックが起こり得る
- aysnc使うと呼び出し側では一瞬で処理が終わる
- 破綻しないのは呼び出し側のスレッドが残ってるから
- タイマーでのポーリングはマシン依存になるので、結果を受け取るのに使ってはいけない
リンク
第1回のリンクです。
わんくま同盟 東京勉強会 #89に行ってきた(その1 MonoGame で作る C# ゲームプログラミング!) - プログラマーな日々
第2回のリンクです。
わんくま同盟 東京勉強会 #89に行ってきた(その2 Knockout.js の利用とカスタムバインディングの利用) - プログラマーな日々
第4回のリンクです。
わんくま同盟 東京勉強会 #89に行ってきた(その4 Dynamics CRM Online を使ってみよう by えムナウさん) - プログラマーな日々