async/await deep dive
Post on 10-May-2015
4.253 Views
Preview:
DESCRIPTION
TRANSCRIPT
async/awaitdeep dive
-Community Open Day 2012-
June 9th, 2012
xin9le
AgendaProfileName鈴木孝明
Twitter Account@xin9le
Bloghttp://xin9le.net/
OccupationProgrammer
HobbyProgramming, Piano, Tennis, English
Agenda1. 非同期処理の基礎
2. 非同期メソッドの概要
3. 非同期メソッドの内部実装
4. WinRTとの相互運用
5. まとめ
Basis for Asynchronous
Sync vs Async Why is it important ?UIスレッド
応答可能
UIスレッド 別スレッド
応答不能
Why is it important ?• UIが長くフリーズするのを防ぐ
• タッチデバイスでは不快感が特に顕著
• I/Oなどをバックグラウンド処理して効率化
• 多機能化によるパフォーマンスの劣化への対処
• 複数コアを利用した並列処理
避けては通れない課題
History Quick Review
Task-based
async/await
Reactive Extensions
Event-based
Async Programming ModelThreadPool
Thread
Quick Review-ちょこっとコードを見てみよう-
About Asynchronous Method
• 修飾した関数は1つ以上のawait演算子を含む
• await演算子以降をコンパイラによって継続渡しに
async Modifier await
await Operator Can• 対象のタスクが完了していない場合、以降の処理を
継続タスクとして登録
• 完了したら、登録しておいた継続タスクを実行
• 待機中、呼び出し元スレッドをブロックしない(= 即座にreturnされる)
return
Can use anywhere• async修飾子はラムダ式や匿名メソッドにも適用可能
• await演算子は式が書ける箇所ならどこでも利用可能
• 継続処理は自動的にUIスレッド上で実行される
• 自前でUIスレッドに処理を戻す必要なし
• 後述の独自Awaitableパターン実装時はその限りではない
• UIスレッドに戻すかどうかは明示的に制御可能
• ConfigureAwaitメソッド
• True : 同期する False : 同期しない
UI Marshaling
Return Value Exception• 非同期メソッドの戻り値の型は以下のいずれか
• void型
• 非同期メソッドの完了を待機する必要がない場合
• イベントハンドラなどで利用
• Task / Task<T>型
• 非同期メソッドの完了を待機したり、戻り値を取得する必要がある場合
• 同期処理と同様の例外処理が可能
• APMやEAPの例外処理はカオスになりがち
Exception Handling
Internal Implementation-dive into asynchronous method-
Decompile Essence• コンパイラはasync/awaitをどう変換しているのか
• 中間言語(IL)を逆コンパイルして解析
• ILSpy (http://wiki.sharpdevelop.net/ILSpy.ashx) が便利
Essence Compiler Requirement
Compiler Requirement
• GetAwaiterメソッドを持つ
• 返されるAwaiterの型は問われない (classでもstructでもOK)
• 自身のメソッドでも拡張メソッドでもOK
-awaitableになるためには-
Compiler Requirement
• INotifyCompletionインターフェースを実装
• OnCompletedメソッドの実装の義務付け
• IsCompletedプロパティを持つ
• GetResultメソッドを持つ
• 戻り値の型は問われない
-awaiterになるためには-
Custom Implementation-Let’s try!!-
Interoperabilitywith WinRT-one step ahead-
Async on WinRT Convert to Task• WinRTの非同期操作は以下のいずれかを実装
• すべてCompletedプロパティを持つ
• 完了時に呼び出されるデリゲートを1度だけ設定可能
• 完了後に設定してもCallbackされる
Progress
Yes No
Resu
lts
Yes IAsyncOperationWithProgress IAsyncOperation
No IAsyncActionWithProgress IAsyncAction
これをawaitできればMetroの開発が楽に!!
Convert to Task Direct await• これらのInterfaceをTaskに変換できればawait可能
• TaskCompletionSource<T>を使って拡張メソッド化
• 内部保持するTaskの完了をSetResultメソッドなどで制御
Direct await .NET Standard• .AsTask();とか毎回×2書きたくない...
• .AsTask();と書かずにawaitするには?
• GetAwaiterを実装すればよい (参照 : コンパイラ要件)
• 以下は完全に同等
.NET Standard• 標準で多数の拡張メソッドが提供されている
• awaitをより高度に扱う場合はAsTaskを利用
• 非同期処理をキャンセルする
• 進捗通知を行う
• 複数の非同期処理がすべて完了するまで待機する
• 以後の処理をUIスレッドに戻さない (etc...)
Today’s Summary-ココだけは押さえよう!!-
Summary Summary• async/awaitはペアで利用する
• 非同期メソッド中にawaitは何度でも書ける
• 残りの処理は継続として登録され、関数から抜ける
• 継続処理は自動的にUIスレッド上で実行される
• 同期処理と同様の例外処理ができる
Summary Summary• コンパイラによって内部的に構造体が生成される
• GetAwaiterメソッドがあればawait可能
• Awaiterになるためには以下の実装が必要
• INotifyCompletionインターフェース
• IsCompletedプロパティ
• GetResultメソッド
Summary Reference• WinRTは非同期処理は4つのInterfaceからなる
• 標準で用意された拡張メソッドでawait可能
• より高度な操作が必要な場合はAsTaskを利用
• 非同期処理のキャンセル
• 進捗通知 (etc...)
Reference Thanks• WinRTとawaitを掘り下げる
http://blogs.msdn.com/b/windowsappdev_ja/archive/2012/04/30/winrt-await.aspx
• 非同期処理http://ufcpp.net/study/csharp/sp5_async.html
• 非同期メソッドの内部実装http://ufcpp.net/study/csharp/sp5_awaitable.html
• Windowsランタイムの非同期性により高速で滑らかなアプリにするhttp://blogs.msdn.com/b/windowsappdev_ja/archive/2012/03/26/windows.aspx
• Windows Developer Days 2012 | Cannel 9http://channel9.msdn.com/Events/Windows-Developer-Days/Windows-Developer-Days-2012
ThanksThank you for your attending.
Enjoy Asynchronous!!with .NET Framework 4.5
top related