SlideShare a Scribd company logo
async/await ダークサイド is 何 
まどべんよっかいち2014/10/18Center CLR Kouji Matsui (@kekyo2)
Profile 
けきょTwitter:@kekyo2Blog: www.kekyo.net 
Center CLR2014/10/01~ 
自転車復活!
Agenda 
非同期処理のダークサイド 
ハードウェイトis 何 
同期コンテキストis 何 
MVVMとコマンドインターフェイス 
うにゃー
ようこそ非同期処理 
ウェルカム&ウェルカムバック非同期!! 
前回の非同期処理の話はもう完璧? 
いまさら恥ずかしくてasyncをawaitした(まどべんよっかいち) 
これからの「async-await」の話をしよう(名古屋GeekBar) 
アタリマエよ? 
コレからは全て非同期処理よ? 
非同期Love既定ね?
ダークサイド非同期処理 
じゃあ、非同期処理のダークサイドについて、いろいろぶちまけて おこうか。 
ア、アナタなに言ってるの 
意味フメイだワ
ハードウェイトis 何 
スレッドブロッキングで死亡
ピットフォールに落ちろ 
ここで処理が完了するのを待ちたいんだ。 
おぉ、Task.Waitなんてあるんだ。awaitなんて、良く分かんないもの使わなくても待てるじゃん。イベント ハンドラから呼ぶときはWaitすればいっか! 
非同期処理メソッド(Taskを返す) 
イベントハンドラはTaskを返さない (返せない)ので、単にWaitで待つ 
「非同期処理対応なんて 
大したことないな(実話)」
刺さる(死) 
ボタンが押された 
Waitはハードウェイトなので、スレッド1は ここで処理を停止する(=UI無応答) 
スレッド1 
スレッド1 
awaitがあるので、ここで非同期 処理を開始して、スレッド1は退出 
メソッドを抜けると、Taskに対して すぐにWaitを呼び出す 
スレッド1 
非同期処理 (HttpClient)
刺さる(死) 
非同期処理が完了すると、 
UIキューに完了を通知する 
スレッド1 
非同期処理 (HttpClient) 
しかしスレッド1はここで 
ハードウェイトしているので、 
UIキューを確認することが出来ない 
永久に動けない 
UI キュー
UIキューって何? 
Win32でいう所の「メッセージキュー」です。Windowsメッセージは、すべてこのUIキューに放 り込まれ、スレッド1(メインスレッド)が一つ一つ拾い上げて処理を行います。 
WPF・ストアアプリで言う所のDispatcher、WinFormsではInvoke/BeginInvokeの操作。 
UIキュー 
ボタンクリック 
スレッド1 
イベントハンドラ1 
イベントハンドラ2 
イベントハンドラ3 
イベントハンドラ4 
基本的にスレッド1だけが、すべての処理を順次行います。 
そのため、ボタンやマウスの操作が、順序を保って処理さ れることが保証されます(同時に実行されない)。 
順番に取り出します
UIキューと非同期処理の関係 
非同期処理の完了は、UIキューに通知されます。スレッド1が別の処理をしていたとしても、 じきにUIキューから通知を拾い上げ、await直後の処理を継続します。 
UIキュー 
(awaitの手前の処理) 
スレッド1 
非同期処理 (HttpClient) 
awaitの続き やってね 
ボタン 
押された 
(awaitの直後の処理) 
①この処理が 
完了すれば 
②これを 
拾い上げて 
③awaitを 
継続できる
ハードウェイトしてしまうと… 
UIキュー 
(awaitの手前の処理) 
スレッド1 
非同期処理 (HttpClient) 
awaitの続き やってね 
ボタン 
押された 
(awaitの直後の処理) 
この処理は 
永遠に完了しない 
拾い上げれない 
実行できない
非同期処理上での待機の教訓 
非同期処理メソッド内で ハードウェイトしてはいけ ません(殆ど絶対) 
シングルスレッドUIシステムが絡まない(=UIキューが無い)場合は、ハードウェイト出来る事も あります(例:コンソールアプリケーション)
ではどうやって対処する? 
①結局awaitするしかない 
②awaitするにはasync化するしかない 
「awaitなんて良く分かんないもの云々」と 言っていても、awaitから逃れる事は出来ない。 
従来技術での代替テクニックは存在しない。
ハードウェイトの種類 
モニターロック(Monitorクラス、lock句) 
lock句については、非同期処理メソッド内(async適用メソッド内)では使えません(コンパイルエラー)。 
try-finallyとMonitorクラスを使って同じことが出来ますが、やってはいけません。 
カーネルオブジェクトによるハードウェイト 
WaitHandleクラスを継承したクラスで、WaitHandle.WaitOne・WaitAny・WaitAllを呼び出す全ての操作。 
ManualResetEvent, AutoResetEvent, Mutex, Semaphoreなど 
間接的に呼び出しているものについても注意!Thread.Join・そしてTask.Wait・Task.WaitAllなど 
これらは全て、前回紹介したNito.AsyncExライブラリに代替同期クラスがあります。 
困った時のNuGetで!! 
https://nitoasyncex.codeplex.com/
同期コンテキストis 何 
COMのアパートメントに似た何か
UIキューで同期しなければおk? 
await後の処理を継続するのに、非同期完了の通知をUIキューに「どうしても」入れなければなら ないのか? 
UIキューに入れなきゃいいんだよね? 
ぶっちゃけ、UIキュー使わない方法は無いの? 
UI無い環境ではどうなるの?
Task.ConfigureAwaitis 何 
TaskクラスにConfigureAwaitメソッドがあり、この引数をfalseと指定すると、UIキューを使わなくなる。 
スレッド1 
スレッド1はすぐ退出 
非同期処理 (HttpClient)
Task.ConfigureAwait(false) 
await後続の処理を、ワーカー スレッドが直接実行する 
非同期処理 (HttpClient) 
ワーカースレッドに通知 
(UIキューを使わない) 
スレッド2 
UI キュー 
スレッド1 
別の作業が出来る
ファーッ?! 
意味不明だけど、要するに 
メインスレッドじゃないと 
ダメって事
Dispatcherでマーシャリングすれば? 
ConfigureAwait(false)により、await以降の処理がワーカースレッド(メインスレッドではない何か) で実行される。 
UIキューを使わないので、応答速度は速い。 
しかし、後続の処理(メソッドの終端まで)では、UIに関する処理を一切行えない。 
Dispatcher使えばおk? 
まぁ、Dispatcher使えばいいんだけど、 何のためにUIキューを無効化したのか? 
UI キュー 
スレッド1
モヤモヤする 
ロジック処理とUI制御処理を、二分出来ないか考える。 
基本的なストラテジーとして、あらかじめ単なるロジック処理をまとめて終わらせておく。その 結果を元に、UIを更新することを考える。 
ロジック処理 
(ビジネスロジックなど) 
データ 
データ 
データ 
UI制御処理 
(データバインディングなど) 
データを渡す 
ConfigureAwait(false)で 
ワーカースレッドが実行してもOK 
普通にawaitする事で、 UIキューを使わせる
ならば、非同期メソッドを独立させよう 
ConfigureAwait(false)しないので、後続の 処理はメインスレッドで実行される 
UI制御処理 
ビジネス 
ロジック 
UIに関係のある操作を行わない 
(ワーカースレッドで実行してもOK)
ややこしい遷移の全貌 
スレッド1 
スレッド1は 
一旦退出 
非同期処理 (HttpClient) 
スレッド2 
UI キュー 
スレッド1 
UIキューに通知
同期コンテキストis 何 
ConfigureAwait(true) とすると、同期コンテキストをキャプチャする。 
ConfigureAwait(false)とすると、同期コンテキストをキャプチャしない。 
日本語か、それはw 
UI キュー 
WPFやWinFormsを使う場合、 
「同期コンテキスト」とは「UIキュー」の事だ 
キャプチャする、とは、UIキューを使って 完了の通知を行う、と読み替えればOK。 
したがって、ConfigureAwait(false)する と、UIキューを使わずに、非同期操作の完 了を処理する。
MVVMとコマンドインターフェイス 
テストが問題
MVVM is 何 
Model–View–ViewModelの略 
Model –View –Controller (MVC)を、XAMLのデータバインディングを前提に構築しなおしたデ ザインパターンの一種。 
UI設計と実装(ビジネスロジックやUI制御)を分離できる。 
ViewModelやModelにロジックを集中させることで、ユニットテストの自動化が容易になる。 
XAML (View) 
<TextBoxText=“{Binding Result}” /> 
ViewModelクラス 
public string Result{ get; set; } 
同じプロパティ名 で自動転送 
ユニット 
テスト 
※本セッションでは、Modelの定義を省略
イベントもバインディングしたい 
ICommandインターフェイスをButton.Commandにバインディングする事で、イベントハンドラをバ インディング出来るようになる。 
データの入出力だけではなく、イベントハンドリングもデータバインディング出来るので、Viewと ViewModel間の通信を統一的に設計できる。 
コードビハインドを駆逐できる。 
XAML (View) 
<Button Command=“{Binding FireStart}” /> 
ViewModelクラス 
public ICommandFireStart{ get; set; } 
同じプロパティ名 で自動転送 
OnFireStart() 
Startボタン
イベントハンドラ内で非同期処理を 
OnFireStartイベントハンドラ内で非同期メソッドを呼び 出すには、async/awaitを指定しなければならない。 
イベントハンドラのシグネチャは決まっている (Action<object>)なので、「asyncvoid」としか書け ない。 
asyncvoid (Taskは返せない) 
ICommandの実装例 
ボタンクリックで Executeが呼び出される
さぁ、ViewModelをテストしよう… 
残念ながら、ユニットテストコードはまともに機能しない 
ICommand.Executeを呼び出して、 ボタンクリックをシミュレート 
ここでいきなり失敗。 
コレクションにイメージが追加され ていない?
何せ、非同期処理なのでね… 
Executeメソッドの呼び出しで処理が開始されたものの、あくまで「非同期処理」なので、バッ クグラウンドでイメージをダウンロードしている。 
しかし、テストコードはすぐに次に進んでしまうので、アサーションに失敗してしまう。 
ここに到達しても、まだダウンロード中なので、 イメージは追加されていない 
非同期処理 (OnFireStart)
わかった!テストでもawaitすればいい!! 
voidExecute(object parameter) 
orz
そこでだ。 
IAsyncCommandなるインターフェイスを作ってしまう。 
ExecuteAsyncメソッドを追加して、これを非同期メソッドとする。 
Executeが呼び出された場合は、Taskを無視する(握りつぶす)事で、 「asyncvoid」の時と同様、処理は非同期実行される。 
この処理は重要で、WPFやストアアプリからは相変わらずExecuteメソッド が呼び出される事に注意。 
Executeが呼び出された場合は、 Taskを無視して非同期処理させる。 
IAsyncCommandの実装例。 
ExecuteAsyncはTaskを返却する 
迂闊にtask.Wait()とか書いたら… 
分かってるワネ?
ViewModelとテストも修正して 
MSTestは非同期メソッドを認識 出来るので、Taskを返してやる 
晴れて普通の非同期メソッド として実装可能に
成功 
やっと完成ネ
まとめ 
とにかく使う事。 
ライブラリやフレームワークを整備するなら、WinRTを習ってどんどん非同期メソッド化してみる。 そして、それを実際に使ってみる。 
従来の.NET Frameworkのクラスライブラリで、Taskを返すバージョンのメソッドがあるなら、そ のメソッドだけを使って実装してみる。 
Taskを返さないメソッドがあるなら、Task.Run()で非同期メソッドシミュレートして使ってみる。 
使い始めると新たな課題が出てくる。良く考察して、早く身に着けてしまおう。使わないうちは、 身につかない、絶対。
ありがとうございました 
本日のコードはGitHubに上げてあります。 https://github.com/kekyo/AsyncAwaitDemonstration 
このスライドもブログに掲載予定です。 http://www.kekyo.net/ 
おいしいにゃー? 
11/1 Unveiled! 
名古屋北生涯学習センター第三集会室

More Related Content

PPTX
テストコードの DRY と DAMP
PDF
Observableで非同期処理
PPTX
世界一わかりやすいClean Architecture
PDF
PHPで大規模ブラウザゲームを開発してわかったこと
PDF
それはYAGNIか? それとも思考停止か?
PDF
ドメイン駆動設計のための Spring の上手な使い方
PDF
Assembly Definition あれやこれ
PDF
オブジェクト指向の設計と実装の学び方のコツ
テストコードの DRY と DAMP
Observableで非同期処理
世界一わかりやすいClean Architecture
PHPで大規模ブラウザゲームを開発してわかったこと
それはYAGNIか? それとも思考停止か?
ドメイン駆動設計のための Spring の上手な使い方
Assembly Definition あれやこれ
オブジェクト指向の設計と実装の学び方のコツ

What's hot (20)

PDF
例外設計における大罪
PDF
ワタシはSingletonがキライだ
PDF
serviceクラスをやめようサブクラスを使おう
PDF
怖くないSpring Bootのオートコンフィグレーション
PDF
C#でわかる こわくないMonad
PDF
.NET 7におけるBlazorの新機能
PDF
いまさら恥ずかしくてAsyncをawaitした
PDF
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
PDF
Unityでオニオンアーキテクチャ
ODP
MVC の Model を考える
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
PDF
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
PDF
ドメイン駆動設計 ( DDD ) をやってみよう
KEY
やはりお前らのMVCは間違っている
ODP
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
PDF
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
PDF
強いて言えば「集約どう実装するのかな、を考える」な話
PDF
Javaのログ出力: 道具と考え方
PDF
GoによるWebアプリ開発のキホン
例外設計における大罪
ワタシはSingletonがキライだ
serviceクラスをやめようサブクラスを使おう
怖くないSpring Bootのオートコンフィグレーション
C#でわかる こわくないMonad
.NET 7におけるBlazorの新機能
いまさら恥ずかしくてAsyncをawaitした
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
Unityでオニオンアーキテクチャ
MVC の Model を考える
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
ドメイン駆動設計 ( DDD ) をやってみよう
やはりお前らのMVCは間違っている
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
強いて言えば「集約どう実装するのかな、を考える」な話
Javaのログ出力: 道具と考え方
GoによるWebアプリ開発のキホン
Ad

Viewers also liked (7)

PDF
これからの「async/await」の話をしよう
PDF
continuatioN Linking
PDF
Async deepdive before de:code
PDF
Thread affinity and CPS
PDF
Handlerさんコンニチワ
PPTX
ChordアルゴリズムによるDHT入門
PDF
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
これからの「async/await」の話をしよう
continuatioN Linking
Async deepdive before de:code
Thread affinity and CPS
Handlerさんコンニチワ
ChordアルゴリズムによるDHT入門
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
Ad

Similar to async/awaitダークサイド is 何 (20)

PDF
ご注文は監視自動化ですか?
PDF
サーバ擬人化ユーザ会キックオフ資料 Slideshare ver
PDF
インフラエンジニアがk8sでアプリを作って見えた今後のインフラ
PPTX
Stac2014 石川
PDF
async/await不要論
PPTX
Jenkinsのある生活
PDF
Android勉強会第二回-非同期処理-
PPTX
Html5 でアプリを作るということ
PDF
Smartphone ui:ux」 de na creative seminar vol.1 レポート
PPTX
サバフェスLt
PDF
Re: ご注文は自動化ですか?[2]
PDF
Nodeにしましょう
PPTX
AWS Direct Connectの構築を自動化(しようと)している話
PDF
AngularJS x Chrome Apps (2014.08.23 #gdgkobe event)
PDF
インタフェースのこころ
PDF
B 2-1 はじめての Windows Azure
PPT
Vsugday2012 summer tokyo_aoyagi
PPT
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
PDF
Titanium Mobile ~本当にあったこわい話~
PDF
Rnncamp01
ご注文は監視自動化ですか?
サーバ擬人化ユーザ会キックオフ資料 Slideshare ver
インフラエンジニアがk8sでアプリを作って見えた今後のインフラ
Stac2014 石川
async/await不要論
Jenkinsのある生活
Android勉強会第二回-非同期処理-
Html5 でアプリを作るということ
Smartphone ui:ux」 de na creative seminar vol.1 レポート
サバフェスLt
Re: ご注文は自動化ですか?[2]
Nodeにしましょう
AWS Direct Connectの構築を自動化(しようと)している話
AngularJS x Chrome Apps (2014.08.23 #gdgkobe event)
インタフェースのこころ
B 2-1 はじめての Windows Azure
Vsugday2012 summer tokyo_aoyagi
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
Titanium Mobile ~本当にあったこわい話~
Rnncamp01

More from Kouji Matsui (20)

PDF
パターンでわかる! .NET Coreの非同期処理
PDF
Making archive IL2C #6-55 dotnet600 2018
PDF
Matrix signal controller and BrainPad overview
PDF
Fun with BrainPad
PDF
What's Functional?
PDF
Pitfall for WioLTE
PDF
How to make the calculator
PDF
Write common, run anywhere
PDF
Locality of Reference
PDF
Nespのコード生成
PDF
You will be assimilated. Resistance is futile.
PDF
How to meets Async and Task
PDF
Beachhead implements new opcode on CLR JIT
PDF
Async DeepDive basics
PDF
真Intermediate languageのキホン
PDF
.NET Coreから概観する.NETのOSSへの取り組み
PDF
Win32 APIをてなずけよう
PDF
式の体を成して無い式を式の体を成すように式と式木で何とかする式
PDF
不健康なIt戦士を健康的にするアレの話
PDF
Final LINQ extensions III
パターンでわかる! .NET Coreの非同期処理
Making archive IL2C #6-55 dotnet600 2018
Matrix signal controller and BrainPad overview
Fun with BrainPad
What's Functional?
Pitfall for WioLTE
How to make the calculator
Write common, run anywhere
Locality of Reference
Nespのコード生成
You will be assimilated. Resistance is futile.
How to meets Async and Task
Beachhead implements new opcode on CLR JIT
Async DeepDive basics
真Intermediate languageのキホン
.NET Coreから概観する.NETのOSSへの取り組み
Win32 APIをてなずけよう
式の体を成して無い式を式の体を成すように式と式木で何とかする式
不健康なIt戦士を健康的にするアレの話
Final LINQ extensions III

async/awaitダークサイド is 何