Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
New Asynchronous Feature for C# 5.0
Search
Ktz
September 30, 2012
Programming
1
440
New Asynchronous Feature for C# 5.0
async / awaitというC# 5.0から備わった新機能についての解説
async / awaitを使ったことによる失敗体験
Ktz
September 30, 2012
Tweet
Share
More Decks by Ktz
See All by Ktz
DuckDB雑紹介(1.1対応版)@DuckDB座談会
ktz
30
9.5k
DuckDB雑紹介
ktz
9
4.6k
Other Decks in Programming
See All in Programming
ニックトレイン登壇資料
ryotakurokawa
0
140
バックエンドNode.js × フロントエンドDeno で開発して得られた知見
ayame113
5
1.3k
本当だってば!俺もTRICK 2022に入賞してたんだってば!
jinroq
0
250
Devinのメモリ活用の学びを自社サービスにどう組み込むか?
itarutomy
0
1.7k
RubyKaigiで手に入れた HHKB Studioのための HIDRawドライバ
iberianpig
0
1k
20250326_生成AIによる_レビュー承認システムの実現.pdf
takahiromatsui
17
5.6k
AHC 044 混合整数計画ソルバー解法
kiri8128
0
300
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
360
英語文法から学ぶ、クリーンな設計の秘訣
newnomad
1
270
PHPのガベージコレクションを深掘りしよう
rinchoku
0
240
Devin入門と最近のアップデートから見るDevinの進化 / Introduction to Devin and the Evolution of Devin as Seen in Recent Update
rkaga
7
3.8k
Modern Angular:Renovation for Your Applications @angularDays 2025 Munich
manfredsteyer
PRO
0
140
Featured
See All Featured
For a Future-Friendly Web
brad_frost
176
9.6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Practical Orchestrator
shlominoach
187
10k
We Have a Design System, Now What?
morganepeng
51
7.5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.8k
GraphQLとの向き合い方2022年版
quramy
45
14k
Designing Experiences People Love
moore
141
23k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Testing 201, or: Great Expectations
jmmastey
42
7.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
135
33k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Transcript
1. 非同期処理ってむずかしい (><)¶
1.1. はじめに¶ • C# 5.0から採用された • async / await •
手軽に非同期処理が書ける
1.2. わたし¶ おなまえ たむらかずひこ twitter ktz_alias • ひよっこC#使い (Lv.1) •
gitムズ過ぎ • bzrかわいいよbzr
1.3. async の決まり事¶ • 戻り値がTaskまたはvoid • コード例は後で
1.4. async Task¶ • 完了するまで後続の処理を止めてくれる • その間は一旦、呼び出し元へ戻る • 呼び出し元で結果欲しい場合に使う
1.5. async Task¶ public async void Foo() { var bar
= await BarAsync(); // 上の結果待ってから続行 return await BazzAsync(bar); } public async Task<int> BarAsync() { ... }
1.6. async void¶ • 結果を待たず、呼び出し元に戻る • 投げっ放しジャーマン
1.7. async void¶ public async void Foo() { await BarAsync();
// 上の結果待たずに続行 await BazzAsync(); } public async void BarAsync() { ... }
1.8. await の決まり事¶ • asyncなメソッドでのみ使用可 • finally, catch, lock内では使用不可 •
awaitableなメソッドにのみ付けれる
1.9. awaitableなメソッド?¶ • GetAwaiter() という名前のメソッド が定義された型 • そんな型を返すメソッド • Duck-Typing
1.10. awaitableなメソッド?¶ class Awatable { ... public Awaiter GetAwaiter() {
} ... }
1.11. Awaiter?¶ • INotifyCompletionインターフェースを実装 • IsCompletedプロパティ • GetResultメソッド • まぁ...そんな型
1.12. Awaiter?¶ struct Awaiter : INotifyCompletion { public bool IsCompleted
{ get; } public T GetResult() {} // from INotifyCompletion void OnCompleted(Action k) {} }
1.13. 標準では...¶ System.Threading.Tasks • Task • Task<T>
1.14. 標準では...¶ Windows.Foundation • IAsyncAction • IAsyncOperation<T> • IAsyncActionWithProgress •
IAsyncOperationWithProgress<T>
1.15. 同期化¶ • await後に元のスレッドに戻ってくる • SynchronizationContextが有効 • ConfigureAwait(false)でも無効化
1.16. 同期化¶ • WinRTでは • WinRTSynchronizationContext
1.17. 同期化¶ 注意 • 直接Taskをインスタンス化した場合 • 同期化されません • STA前提のメソッドは死ぬ
1.18. async / awaitの内側¶ • コンパイラの中の人が • 継続渡し、状態遷移機械などの • 黒魔術を駆使して
• 同期的な記述を非同期処理に変換
1.19. async / awaitの内側¶ ↓詳しくはココ http://blogs.msdn.com/b/ windowsappdev_ja/archive/ 2012/04/30/winrt-await.aspx
1.20. async / awaitでの苦労話¶ ココから本題
1.21. async / awaitでの苦労話¶ 1. 自前のTaskでawaitableなメソッド呼ぶ 結果 • 後続の実行前にTaskが完了する
1.22. async / awaitでの苦労話¶ await Task.Run(async () => { await
FooAsync(); // ↓実行されない return await BarAsync(); });
1.23. async / awaitでの苦労話¶ どうする? • 解決方法なし • 直接作ったTask中の使用はあきらめましょう
1.24. async / awaitでの苦労話¶ 1. Linqと相性が悪い • Linq内でawaitすると • 戻り値がIEnumerable<Task<TResult>>
1.25. async / awaitでの苦労話¶ var r = sources.Select(async (s) =>
{ return await BarAsync(s); });
1.26. async / awaitでの苦労話¶ • 値を取り出すために • foreachで回す必要があり
1.27. async / awaitでの苦労話¶ foreach (var task in results) {
var result = await task; }
1.28. async / awaitでの苦労話¶ • よく訓練されたLinq使い • foreachを嫌う • Linqのうまみ半減
1.29. async / awaitでの苦労話¶ どうする? • Linqとawaitの併用はあきらめましょう
1.30. async / awaitでの苦労話¶ 1. Task.Wait()で死ねる • 同期コンテキスト有効で • 非同期処理連鎖の内側で呼ぶと
• デッドロック
1.31. async / awaitでの苦労話¶ int Foo() { // ↓ 中でawaitするメソッド
var task = BarAsync(); // ココでお見合い task.Wait(); return task.Result; }
1.32. async / awaitでの苦労話¶ • 同期化のために • なかのawaitが呼出し元を待つから ↓詳しくはココミテ http://blogs.msdn.com/b/pfxteam/
archive/2012/04/12/10293249.aspx
1.33. async / awaitでの苦労話¶ どうする? • あきらめま(ry
1.34. async / awaitでの苦労話¶ 1. ならばと、GetAwaiter().GetResult()で無理矢理呼ぶ
1.35. async / awaitでの苦労話¶ public async void Foo() { var
task = BarAsync(); task.GetAwaiter().GetResult(); }
1.36. async / awaitでの苦労話¶ • 結果 • はい、デッドロック
1.37. async / awaitでの苦労話¶ どうする? • あ(ry
1.38. async / awaitでの苦労話¶ 1. Parallel.Foreachの中では使えない
1.39. async / awaitでの苦労話¶ Paralle.Foreach(list, async (x) => { await
Foo(x); }); • すべてのアクション完了まで待ってほしいのに... • Task.Run同様、投げっ放しジャーマン
1.40. async / awaitでの苦労話¶ どうする? • 気合いで非同期版作って下さい ↓ココミテ http://blogs.msdn.com/b/pfxteam/ archive/2012/03/04/10277325.aspx
1.41. async / awaitでの苦労話¶ 1. ユニットテストしづらい • NUnitはasync / await未対応
• 何も考えず走らせると • テストが実行されず終了(CLI版)
1.42. async / awaitでの苦労話¶ どうする?
1.43. async / awaitでの苦労話¶ CUI Runnerの場合 • 同期化されていないので • Taskk.Wait()
or GetAwaiter().GetResult()で待たせる
1.44. async / awaitでの苦労話¶ public void RunTest(Func<Task> inTest) { inTest.GetAwaiter().GetResult();
} [Test] public void _TestSomething() { RunTest(async () => { ... }); }
1.45. async / awaitでの苦労話¶ GUI Runnerの場合 • 自前の同期コンテキストを気合いで実装 • 割と安定してる
• けどグローバルな存在なので、ほかでこっそり使われると死ねる
1.46. WinRTのハマりどころ¶ • Windowsストアアプリ作成のためのAPIセット • 非同期処理を多用 • async / awaitの知識必須
1.47. Windowsストアアプリ¶ • Met(検閲により削除)... • とか言うと • MSの方から来た人に手招きされるかもなので注意
1.48. WinRTでの苦労話¶ 1. Windows.Storage APIの使用 スレッドまたいで使用するとSIBOU ArgumentException 範囲外です • (何が?)
COMException その他のエラー • (追跡不能)
1.49. WinRTでの苦労話¶ STAの制約っぽい • スレッドをまたがない • 再取得すると問題出ない
1.50. WinRTでの苦労話¶ 1. BackgroundTask • awaitすると • 戻ってくる前に完了状態になっちゃう
1.51. WinRTでの苦労話¶ どうする? • defferalを取得しておけば待ってくれる • GetDefferal() • 終わったらdefferalのComplete()呼ぶ
1.52. WinRTでの苦労話¶ 1. BackgroundTask スレッドの生成がアプリ本体とは異なる。 • メインスレッドがParallel#ForEachの中に入ってきた。
1.53. WinRTでの苦労話¶ 1. BackgroundTask • 中でTask.Wait()してしまっていたので • デッドロックした • /(^o^)\
1.54. まとめ¶ • C# 5.0で非同期処理が手軽に使えるようになった • けど...ハマりどころ多数 • まぁ、まるちすれっどですゆえ
1.55. まとめ¶ (・ワ・)