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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Ktz
September 30, 2012
Programming
1
460
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
10k
DuckDB雑紹介
ktz
9
5k
Other Decks in Programming
See All in Programming
Rails Girls Tokyo 18th GMO Pepabo Sponsor Talk
yutokyokutyo
0
150
Swift at Scale: Where Performance Really Comes From
kateinoigakukun
0
120
JPUG勉強会 OSSデータベースの内部構造を理解しよう
oga5
2
200
2026年は Rust 置き換えが流行る! / 20260220-niigata-5min-tech
girigiribauer
0
140
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
860
ふん…おもしれぇ Parser。RubyKaigi 行ってやるぜ
aki_pin0
0
110
AI時代のキャリアプラン「技術の引力」からの脱出と「問い」へのいざない / tech-gravity
minodriven
22
7.9k
Oxlint JS plugins
kazupon
1
1.1k
NetBSD+Raspberry Piで 本物のPSGを鳴らすデモを OSC駆動の7日間で作った話 / OSC2026Osaka
tsutsui
1
120
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
1
360
CSC307 Lecture 06
javiergs
PRO
0
700
AIに仕事を丸投げしたら、本当に楽になれるのか
dip_tech
PRO
0
150
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.2k
The agentic SEO stack - context over prompts
schlessera
0
660
WCS-LA-2024
lcolladotor
0
470
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
78
How STYLIGHT went responsive
nonsquared
100
6k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
65
How to Think Like a Performance Engineer
csswizardry
28
2.5k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
280
How to build a perfect <img>
jonoalderson
1
5.2k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
230
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. まとめ¶ (・ワ・)