SlideShare a Scribd company logo
1 of 116
Download to read offline
www.dotnetconf.net
パターンでわかる!
.NET Coreの
非同期処理
2019.10.5 .NET CONF 2019 MEETUP IN AICHI
- KOUJI MATSUI (@KOZY_KEKYO, @KEKYO2)
Kouji Matsui – kozy, kekyo
• NAGOYA city, AICHI pref., JP
• Twitter – @kozy_kekyo, @kekyo2 /
Facebook
• Self employed (I’m looking for a job)
• Microsoft Most Valuable Professional VS
and DevTech 2015-
• Certified Scrum master / Scrum product
owner
• Center CLR organizer.
• .NET/C#/F#/IL/metaprogramming or like…
• Bike rider
Agenda
.NET Core 3とC# 8.0で完成した.NET非同期処理
.NET非同期処理のおさらい
.NET非同期処理の現実と設計
追加された非同期処理の要素
What’s new features
本日は、以下のことをお話します:
.NET非同期処理のおさらい
◦ 概要と基本的な書き方
◦ コンソールアプリケーションとGUIアプリケーションとの違い
◦ お勧めしたいプラクティスとアンチパターン
.NET非同期処理の現実と設計
◦ 現実的なアプリケーションへの適用と課題
追加された非同期処理の要素
◦ 足りなかったもの・足りていると勘違いされていたもの
What’s new features
.NET Core 3とC# 8.0で、.NETの非同期処理はついに完成
Task
async-await
ValueTask
IAsyncEnumerable
Awaitable foreach
世
代
What’s new features
.NET Core 3とC# 8.0で、.NETの非同期処理はついに完成
Task
async-await
ValueTask
IAsyncEnumerable
Awaitable foreach .NET Core 3
世
代
What’s new features
.NET Core 3とC# 8.0で、.NETの非同期処理はついに完成
Task
async-await
ValueTask
IAsyncEnumerable
Awaitable foreach
非同期処理記述の
容易さの壁 (1)
非同期処理記述の
容易さの壁 (2)
世
代
今日は、壁より前の話や内部の話はしません。
なぜ非同期で処理を行う必要があるのかについては、
「Async訪ねて3000里」を参照
.NET非同期処理のおさらい
非同期処理、ポイントを押さえれば難しくありません。なの
に、正しく書けてない、場合によっては危険なコードが散見さ
れます。
.NET Core 3とC# 8.0で劇的に便利になったので、そろそろマス
ターしちゃいましょう!
非同期処理を記述する際に遭遇する問題のパターンと、解決
の方策を示します。
基本的な操作(1) – ファイルアクセス
コンソールアプリケーションで非同期処理してみる
ファイル出力を非同期処理で書いてみる
基本的な操作(1) – ファイルアクセス
任意のデータを
ファイルに出力する
FileAccessWithAsync.csproj
基本的な操作(1) – ファイルアクセス
注目すべきポイント
基本的な操作(1) – ファイルアクセス
I/O操作はすべて(Taskを返却する)
非同期対応メソッドを使用してawaitする
基本的な操作(1) – ファイルアクセス
メソッド中でawaitを使う場合は、メソッド
宣言でasyncとマークし、Taskを返す
基本的な操作(1) – ファイルアクセス
C# 7.1から、Mainメソッドが
Taskを返せるようになった
基本的な操作(1) – ファイルアクセス
FileStreamクラス固有:
falseまたは省略した場合は、
非同期I/Oはワーカースレッド
によるシミュレート
ファイルアクセス Appendix
ファイルアクセスでよく使われる
Fileクラスのメソッド
ファイルアクセス Appendix
Task.Runを使って、ワーカースレッドでシ
ミュレートするのと同じなので、非効率
ファイルアクセス Appendix
Mainメソッドの対処方法:
C#7.0以前を使う場合は、このように非同期
メソッドにバイパスする
(但しコンソールアプリケーションのみ)
基本的な操作(2) – 独立した非同期処理
非同期処理を行うメソッドを作る
非同期処理を行うクラスライブラリを作る
基本的な操作(2) – 独立した非同期処理
指定されたURLからJSON形式
のデータをダウンロードして
パースするライブラリ
IndependentLibrary.csproj
基本的な操作(2) – 独立した非同期処理
注目すべきポイント
基本的な操作(2) – 独立した非同期処理
メソッド中でawaitを使う場合は、メソッド
宣言でasyncとマークする
基本的な操作(2) – 独立した非同期処理
メソッド内部で非同期処理を行い、結果
を値として返すので、Task<T>型とする
基本的な操作(2) – 独立した非同期処理
Task<T>又はTaskを返す場合に、
メソッド名末尾にAsyncをつける
(必須ではないが強く推奨)
`async`とマークした場合、
ではないことに注意
独立した非同期処理 Appendix
末尾にAsyncとつける推奨について:
1. 末尾にAsyncとついていれば、使用者が非同期処理対応の
メソッドを容易に見分けられる(インテリセンスを活用
する意味でも重要)
2. よく見られる誤ったプラクティス: `async`とマークした場
合に、メソッド名末尾にAsyncと付ける…
→ TaskやTask<T>を返した場合に、末尾にAsyncを付ける
Streamクラスのメンバー一覧
独立した非同期処理 Appendix
抽象度の高いインターフェイス定義。
メソッドは値を返さない
誤ったプラクティスと考える理由
InterestingService.csproj
独立した非同期処理 Appendix
共通のインターフェイスメソッドを
実装し、ログを出力する
独立した非同期処理 Appendix
ログ出力の負荷を軽減するため、バックグラ
ウンドで出力するように改良。
呼び出し元はログがバックグラウンドで出力
されているかどうかを気にしなくても良い
(=通知手段がないので出来ない)
独立した非同期処理 Appendix
ウェブサービスに
アクセスする実装
独立した非同期処理 Appendix
メソッド中でawaitを使う場合は、メソッド
宣言でasyncとマークする
独立した非同期処理 Appendix
`async`とマークしているが、
末尾にAsyncと命名できない…
`async`のマークは、内部でawaitキーワードを使っ
たかどうかであって、非同期処理をするかどうか
(インターフェイスの規定)とは関係がない
独立した非同期処理 Appendix
このメソッドは、同期的に値を返さない。
内部の処理は同期的に行われているかもしれないし、非同期的に行われて
いるかもしれない(わからない)。
非同期的に行われているのであれば、その結果を知ることは出来ない。
このインターフェイスメソッドの
真の意味
WPFやWinFormsで非同期処理をおこなう
基本的な操作(3) – GUI内での操作
基本的な操作(3) – GUI内での操作
ボタンが押されたら
ファイルを生成する
WPFアプリケーション
WpfAppWithAsync.csproj
基本的な操作(3) – GUI内での操作
注目すべきポイント
基本的な操作(3) – GUI内での操作
メソッド中でawaitを使う場合は、メソッド
宣言でasyncとマークする
基本的な操作(3) – GUI内での操作
イベントハンドラの戻り値をTaskにする
ことは出来ない。その場合、voidだけが
非同期メソッドとして許される
基本的な操作(3) – GUI内での操作
イベントハンドラの戻り値を
Taskにすることは出来ない
基本的な操作(3) – GUI内での操作
メソッド名末尾にAsyncと付けるプラクティスの背景と
同じことが、イベントハンドラについても言えます
このメソッドは、同期的に値を返さない。
内部の処理は同期的に行われているかもしれないし、非同期的に行われて
いるかもしれない(わからない)。
非同期的に行われているのであれば、その結果を知ることは出来ない。
基本的な操作 Appendix
戻り値の型 直接的な意味 処理の詳細
Task<T> 非同期処理を行いT型の結果
を返す
非同期処理を行い、処理完了後に
結果を値として返す
Task 非同期処理を行い結果を返さ
ない
非同期処理を行い、処理完了後に
完了したことだけが通知される
T 同期処理でT型の結果を返す、
又は結果を返しつつ非同期処
理の状態を返さない
通常の値を返すメソッド。しかし
場合によっては非同期処理が走っ
ているかもしれない
void 同期処理で結果を返さない、
又は非同期処理で状態も結果
も返さない
通常の値を返さないメソッド。し
かし場合によっては非同期処理が
走っているかもしれない
.NET非同期処理の現実と設計
ここまでで、基本的な非同期処理の実装の方法を再確認して
きました。
この節では、現実に発生しうる問題について、もう少し掘り
下げます。
現実と設計(1) – 競合と回避
非同期処理中に競合条件が発生する場合、その回避方法を確
認します。
回避方法は非同期処理特有で、従来の手法が通用しないこと
を知ってください。
現実と設計(1) – 競合と回避
100回実行(つまり、100回インクリメント
されるはず)
RaceConditionWithAsync.csproj
ファイル内の数値文字列を
インクリメントして
ファイルに書き戻す
現実と設計(1) – 競合と回避
非同期処理
Task.WhenAllで、100個のTaskを
並列実行することになる
現実と設計(1) – 競合と回避
100にならない…
→ 排他処理を何もしていないので、
競合が発生している
現実と設計(1) – 競合と回避
awaitを使っていると、lockステートメントで
モニターロックは出来ない
(C#コンパイルエラー)
モニターロック(ミューテックス)で
競合を回避したい、が…
現実と設計(1) – 競合と回避
モニターロックを手動で構成…
現実と設計(1) – 競合と回避
SynchronizationLockException:
モニターロックが異なるスレッドで
解除されようとしている
現実と設計(1) – 競合と回避
1 2 3 4
await
await
await
継続処理用ワーカースレッド群
(スレッドプールから取得)
awaitの前後で、処理スレッドが変わる
(かもしれない)
現実と設計(1) – 競合と回避
1 2 3 4
await
await
await
モニターロック取得スレッド
モニターロック解放スレッド
スレッドが一致していないので例外が発生
現実と設計(1) – 競合と回避
つまりこの方法は根本的にダメ。
C#コンパイラが親切にlockを
使わせないようにしている
現実と設計(1) – 競合と回避
NuGetパッケージ: Nito.AsyncEx
Stephen Cleary氏の作品
ほぼlockステートメントと同じように使えて、
非同期処理対応(排他待機をawait出来る)
現実と設計(1) – 競合と回避
.NET標準(ハードウェイト) Nito.AsyncEx(非同期処理対応)
Monitor, lockステートメント AsyncLock, AsyncMonitor
Mutex AsyncLock
Semaphore AsyncSemaphore
ManualResetEvent AsyncManualResetEvent
AutoResetEvent AsyncAutoResetEvent
ReaderWriterLock AsyncReaderWriterLock
しかし、そもそも排他制御を行って
いると、オーバーヘッドでパフォー
マンスが上がらないと言う問題があ
ります(重要)
他にもSlim版(SemaphoreSlimなど)がありますが、ハードウェ
イトのみないし、部分的に非同期に対応しているのみなので、
非同期処理には推奨しません
Nito.AsyncExを使うと、非同期処理
で安全に排他制御できます
現実と設計(2) – GUIとスレッド
GUIアプリケーションで非同期処理を行う場合は、コンソー
ルアプリケーションとは異なる動きをします。
なぜ、GUIアプリケーションでは非同期処理が強く推奨され
るのか、について掘り下げます。
現実と設計(2) – GUIとスレッド
ボタンが押されたら
ファイル内の数値文字列を
インクリメントする
WPFアプリケーション
WpfAppRaceConditionWithAsync.csproj
現実と設計(2) – GUIとスレッド
GUIアプリケーションでも
非同期処理は普通に使える
現実と設計(2) – GUIとスレッド
1 2 3 4
await
await
await
①がメインスレッド
その他はワーカースレッド (?)
ワーカースレッドで実行され
たら例外で死ぬのでは?
現実と設計(2) – GUIとスレッド
こう書くべき??
いいえ、Dispatcherを使ってメインスレッドに
明示的に転送しなくても問題ありません!
なぜならば…
現実と設計(2) – GUIとスレッド
1
await
await
await
実際にはメインスレッドしか
使われないからです!!
メインスレッドで実行される
現実と設計(2) – GUIとスレッド
1
await
await
await
根本的な疑問「なぜ非同期処理をGUIアプリケー
ションに適用すると、ユーザーインターフェイス
が固まらないのですか?」
現実と設計(2) – GUIとスレッド
1
await
await
await
awaitすると、メインスレッドは一時的にApplication.Run()の内部に戻ること
が出来て、非同期処理が完了するまでは、別のイベントを処理できます
(ボタンクリックイベント処理や、描画処理など)
Application.Run()
OnClick
OnRender
Application.Run()
Application.Run()
現実と設計(2) – GUIとスレッド
1 2 3 4
await
await
await
await後の処理を
「継続処理」と呼びます
継続処理 (1)
継続処理 (2)
継続処理 (3)
コンソールアプリケーションと
どう違うのか?
現実と設計(2) – GUIとスレッド
1 2 3 4
await
await
await
デフォルトでは、継続処理の実行には、必ず
ワーカースレッドが割り当てられます
(メインスレッドとの区別はほとんどない)
継続処理 (1)
継続処理 (2)
継続処理 (3)
現実と設計(2) – GUIとスレッド
継続処理 (1)
継続処理 (2)
継続処理 (3)
1
await
await
await
WPFやWinFormsでは、継続処理の実行に、
常にメインスレッドが割り当てられます。
この制御を行っているのが、
SynchronizationContextの派生クラスです
現実と設計(2) – GUIとスレッド
いつもメインスレッドが継続処理を実行
しているとしたら、こうやって書いてい
るのと同じようなものでは?
(つまり、遅いのでは?)
(厳密には違うのですが)
パフォーマンスの懸念がある点では
その通りです…
現実と設計(2) – GUIとスレッド
そこで、ConfigureAwait()を使います
await
await
await
1
現実と設計(2) – GUIとスレッド
1 2 3 4
await
await
await
WPFデフォルトの挙動を無視し、以降は
ワーカースレッドを割り当てるようになる
もはや必ずワーカースレッドで実行されるので、
UIにアクセスする場合は、Dispatcherを使う必要があります
現実と設計(2) – GUIとスレッド
1 2 3 4
await
await
await
ワーカースレッド間の転送は比較的
低コストなので、この間の継続処理
は実行効率が高くなる
ここはメインスレッドに
転送するコストが高い
現実と設計(3) – 頻出パターン
非同期処理には、特有のパターンがあります。
うまくこのパターンに当てはめれば、高効率かつ劇的に簡単
に実装できるようになります。
競合と排他を避けるためにも、このパターンに乗せてくださ
い。
現実と設計(3) – 頻出パターン
XMLデータをダウンロードして
パースする
非同期パース対応(.NET Core 3から)
AggregateThingsWithAsync.csproj
現実と設計(3) – 頻出パターン
気象庁防災情報
XMLフォーマット形式電文
(中身はAtomフィード)
現実と設計(3) – 頻出パターン
Atomフィードのエントリn個を
現実と設計(3) – 頻出パターン
ダウンロードしてパースし、
現実と設計(3) – 頻出パターン
コメントを抽出する
現実と設計(3) – 頻出パターン
2重ループ
現実と設計(3) – 頻出パターン
ループといえばLINQ
現実と設計(3) – 頻出パターン
最初のAtomフィードの
ダウンロードは同じ
現実と設計(3) – 頻出パターン
内側のループに注目して、Task
を返すメソッドやラムダ式に
する
現実と設計(3) – 頻出パターン
非同期ラムダブロック: Task<Xelement[]>
現実と設計(3) – 頻出パターン
XML LINQ
現実と設計(3) – 頻出パターン
Task.WhenAllで、複数のTaskを一度に
非同期待機する
現実と設計(3) – 頻出パターン
並列実行され、
やがて結果がまとめて返される
現実と設計(3) – 頻出パターン
結果を全て出力
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
動きを振り返ってみます
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
foreachの2重ループ
逐次実行
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
ChattyなUIへのアクセス
(GUIの場合、ボトルネックになりうる)
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
TextTextTextTextTextTextText
WriteLine
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
WriteLine
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
TextTextTextTextTextTextText
WriteLine
LINQでそれぞれの
Textを集約
Task.WhenAllで
全部の非同期
を集約Task
Task
Task
Task
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
TextTextTextTextTextTextText
WriteLine
Task
Task
Task
Task
内側の処理をそれぞれ独立させて、
相互に依存しないようにします
並列実行性が高まります(安全)
→モデル設計 M-(V-VM)
現実と設計(3) – 頻出パターン
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
TextTextTextTextTextTextText
WriteLine
全部の非同期処理を集約
するだけ
全部集約されてから、UIにアクセス
裏を返すと全部集約されないと
UIにアクセスできない
(トレードオフ)
現実と設計 Appendix
補足
現実と設計 Appendix
ハードウェイト(ハードブロック)
◦ スレッドを(WindowsやLinuxなどのOSカーネルの機能で)一時停止させること。非同
期処理に対して、非互換。例外やデッドロックを引き起こす可能性があります。
◦ Thread.Sleep(), Thread.Join()
◦ Monitor.Enter()
◦ WaitHandle.WaitOne(), WaitHandle.WaitAny(), WaitHandle.WaitAll()
◦ Task.Wait(), Task.Result
いつも言っていますが、ここまでの解説で、
上記は一切使っていません。
「Task.Wait(), Task.Resultは使いません・使えません・
使う必要がありません!!」
現実と設計 Appendix
非同期処理(待機可能・Awaitable)
◦ 実行単位をスレッドではなく、抽象的なタスクとみなし、タスクを一
時停止させる。タスクを実行するのはスレッドですが、特定のタスク
がいつも特定のスレッドで実行されるとは限りません。
◦ Task.Delay()
◦ Stream.ReadAsync(), Stream.WriteAsync()
◦ TextReader.ReadLineAsync(), TextWriter.WriteLineAsync()
◦ HttpClient.GetAsync(), HttpClient.PostAsync()
上記は全てTask又はTask<T>を返します。
現実と設計 Appendix
ハードウェイトを行うメソッドを非同期処理と混ぜて安全に
(かつパフォーマンスを最大化して)使用するのは、トップレ
ベルの技術者でも非常に困難です(あるいは不可能)。
つまり、やりたくなったら
何かが間違っています
いやでも今自分が遭遇している問題は、当てはまらない
レアケースだから… と言っている問題も間違いです
追加された非同期処理の要素
ValueTaskはTaskのメモリ確保コストを削減します。
非同期イテレーターインターフェイスが、標準定義され、非
同期イテレーターを列挙する構文・列挙可能にする構文が、
C#8.0で追加されました。
非同期イテレーターを活用すれば、モデル実装がより簡単に
なります。
追加された非同期処理の要素(1) – ValueTask
ValueTaskをTaskの代わりに使っていきたい動機について。
なぜ効率が良いのか?
追加された要素(1) – ValueTask
ValueTaskはTaskの構造体版
追加された要素(1) – ValueTask
AggregateThingsWithAsync.csproj
追加された要素(1) – ValueTask
1. Taskで宣言していたところを機械的にValueTaskに置
き換え出来る。
2. Taskで出来ることはValueTaskでもだいたいできる。
3. ValueTask.AsTask()を呼び出せばTaskに変換できる。
ValueTask.WhenAllはないが、Taskを
返す非同期処理を混ぜて使える
何が嬉しいの?
◦ もし、非同期処理がその場で完了した場合(たとえば、ReadLineAsync()
の読み取りがバッファリングされていたデータなどで直ぐに返せるな
ど)、TaskだとTaskクラスのインスタンス生成にコストが掛かるけど、
ValueTaskならほとんどコストがかからない(構造体だから)
◦ 非同期待機が実際に発生する場合に、初めて内部でTaskのインスタンス
が生成される。
追加された要素(1) – ValueTask
つまり?
async-await構文でawaitしまくるコードを書いた場合:
◦ Taskだとawaitの度にTaskのインスタンスが生成されるので、効率が悪い
◦ ValueTaskだと結果が直ぐに得られる場合は、インスタンス生成コスト
が発生しない
追加された要素(1) – ValueTask
注意: ValueTaskを使う場合は、
System.Threading.Tasks.Extensions
パッケージを追加する必要があります
追加された要素(2) – 非同期イテレーター
Task.WhenAllが配列を返す件。
yield returnを非同期処理と組み合わせて使えます。
追加された要素(2) – 非同期イテレーター
データ群の処理方法
foreachによる逐次処理 Task.WhenAllによる集約処理
メリット 従来のループ手法をそのまま適用
できる。
出力やUIへの反映が逐次実行され
る(インタラクティブ性・スト
リーミング)
集合演算に根付く考え方に適合する
なら、非常に直感的で高レベルな記
述が可能(LINQ)。
モデル設計として独立させやすい。
並列実行される。
デメリット 並列処理がやりにくい、あるいは
そのままでは出来ない。
モデル設計として処理を完全に分
離することが難しい。
全てのデータが集約されてからしか、
結果にアクセスできない(配列)。
追加された要素(2) – 非同期イテレーター
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
WriteLine
TextTextTextTextTextTextText
追加された要素(2) – 非同期イテレーター
entry Text
Text
Text
entry Text
Text
entry Text
Text
Text
Text
entry Text
TextTextText
TextText
TextTextText
Text
Text
Text
Text
Text
Text
Text
WriteLine
この部分を、データが得られたところ
から逐次実行できないものか…
AggregateThingsWithAsync.csproj
追加された要素(2) – 非同期イテレーター
追加された要素(2) – 非同期イテレーター
IAsyncEnumerable<T>で、列挙可能で
かつ非同期処理を実現できる
追加された要素(2) – 非同期イテレーター
普通にawaitできる
追加された要素(2) – 非同期イテレーター
IEnumerable<T>と同じように、
yield returnで要素を返せる
追加された要素(2) – 非同期イテレーター
実装の詳細が外部に漏れていない、
真に独立したモデルメソッドを実現
追加された要素(2) – 非同期イテレーター
非同期イテレーターは、
新しいawait foreachという構文で、
非同期的に列挙できる
追加された要素(2) – 非同期イテレーター
awaitを付けたからasyncを忘れずに
追加された要素(2) – 非同期イテレーター
非同期イテレーターとは?
ValueTaskを使う。
つまり、連続してすぐに値を返せる場合は、
Taskよりもコストが低い
追加された要素(2) – 非同期イテレーター
foreachによる逐次処理 Task.WhenAllによる集約処理 非同期イテレータを使う処理
メリット 従来のループ手法をそのま
ま適用できる。
出力やUIへの反映が逐次実
行される(インタラクティ
ブ性・ストリーミング)
集合演算に根付く考え方に適
合するなら、非常に直感的で
高レベルな記述が可能
(LINQ)。
モデル設計として独立させや
すい。
並列実行される。
従来のループ手法をそのまま適
用できる。
出力やUIへの反映が逐次実行さ
れる(インタラクティブ性・ス
トリーミング)
モデル設計として独立させやす
い。
デメリット 並列処理がやりにくい、あ
るいはそのままでは出来な
い。
モデル設計として処理を完
全に分離することが難しい。
全てのデータが集約されてか
らしか、結果にアクセスでき
ない(配列)。
並列処理がやりにくい、あるい
はそのままでは出来ない。
Any question? Thank you for join!!
スライドのコードは全てここにあります:
https://github.com/kekyo/dotnetconf2019
Any question? Thank you for join!!
https://github.com/kekyo/dotnetconf2019

More Related Content

What's hot

エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Shin Ohno
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーToru Makabe
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Akihiro Suda
 
できる!並列・並行プログラミング
できる!並列・並行プログラミングできる!並列・並行プログラミング
できる!並列・並行プログラミングPreferred Networks
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する増田 亨
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで増田 亨
 
C#でわかる こわくないMonad
C#でわかる こわくないMonadC#でわかる こわくないMonad
C#でわかる こわくないMonadKouji Matsui
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話Kumazaki Hiroki
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善増田 亨
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードShigenori Sagawa
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する増田 亨
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 

What's hot (20)

エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
できる!並列・並行プログラミング
できる!並列・並行プログラミングできる!並列・並行プログラミング
できる!並列・並行プログラミング
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで
 
C#でわかる こわくないMonad
C#でわかる こわくないMonadC#でわかる こわくないMonad
C#でわかる こわくないMonad
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 

Similar to パターンでわかる! .NET Coreの非同期処理

C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021Atsushi Nakamura
 
2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMFAtomu Hidaka
 
.NETラボ2021年10月 .NETの過去と現在
.NETラボ2021年10月 .NETの過去と現在.NETラボ2021年10月 .NETの過去と現在
.NETラボ2021年10月 .NETの過去と現在TomomitsuKusaba
 
Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0Atsushi Nakamura
 
.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデートTomomitsuKusaba
 
2014 1018 OSC-Fall Tokyo NETMF
2014 1018 OSC-Fall Tokyo NETMF2014 1018 OSC-Fall Tokyo NETMF
2014 1018 OSC-Fall Tokyo NETMFAtomu Hidaka
 
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜bitbank, Inc. Tokyo, Japan
 
そろそろレガシーな.Net開発をやめなイカ?
そろそろレガシーな.Net開発をやめなイカ?そろそろレガシーな.Net開発をやめなイカ?
そろそろレガシーな.Net開発をやめなイカ?Yuta Matsumura
 
Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Narami Kiyokura
 
2014 0228 OSC-Spring Tokyo NETMF
2014 0228 OSC-Spring Tokyo NETMF2014 0228 OSC-Spring Tokyo NETMF
2014 0228 OSC-Spring Tokyo NETMFAtomu Hidaka
 
20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux20170527 inside .NET Core on Linux
20170527 inside .NET Core on LinuxTakayoshi Tanaka
 
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)シスコシステムズ合同会社
 
新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ慎一 古賀
 
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?Takashi Sogabe
 
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用de:code 2017
 
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)NTT DATA Technology & Innovation
 
わんくま東京勉強会#46 Azureセッション資料
わんくま東京勉強会#46 Azureセッション資料わんくま東京勉強会#46 Azureセッション資料
わんくま東京勉強会#46 Azureセッション資料Shinichiro Isago
 

Similar to パターンでわかる! .NET Coreの非同期処理 (20)

C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021
 
2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF2015 0227 OSC-Spring Tokyo NETMF
2015 0227 OSC-Spring Tokyo NETMF
 
.NETラボ2021年10月 .NETの過去と現在
.NETラボ2021年10月 .NETの過去と現在.NETラボ2021年10月 .NETの過去と現在
.NETラボ2021年10月 .NETの過去と現在
 
Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0
 
.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート.NET 6の期待の新機能とアップデート
.NET 6の期待の新機能とアップデート
 
2014 1018 OSC-Fall Tokyo NETMF
2014 1018 OSC-Fall Tokyo NETMF2014 1018 OSC-Fall Tokyo NETMF
2014 1018 OSC-Fall Tokyo NETMF
 
最速C# 7.x
最速C# 7.x最速C# 7.x
最速C# 7.x
 
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜
持続的な運用開発のために社内基盤を整えている話 〜auditのCI組み込みやlintの社内PKG化〜
 
そろそろレガシーな.Net開発をやめなイカ?
そろそろレガシーな.Net開発をやめなイカ?そろそろレガシーな.Net開発をやめなイカ?
そろそろレガシーな.Net開発をやめなイカ?
 
Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門Visual Studioで始めるTypeScript開発入門
Visual Studioで始めるTypeScript開発入門
 
2014 0228 OSC-Spring Tokyo NETMF
2014 0228 OSC-Spring Tokyo NETMF2014 0228 OSC-Spring Tokyo NETMF
2014 0228 OSC-Spring Tokyo NETMF
 
20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux
 
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)
Cisco Modeling Labs (CML)を使ってネットワークを学ぼう!(DevNet編)
 
Netmf-180224
Netmf-180224Netmf-180224
Netmf-180224
 
新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ
 
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
 
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用
[TL04] .NET 15 周年の今こそ考えるクラウドネイティブ アプリケーションと .NET の活用
 
Net fringejp2016
Net fringejp2016Net fringejp2016
Net fringejp2016
 
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
 
わんくま東京勉強会#46 Azureセッション資料
わんくま東京勉強会#46 Azureセッション資料わんくま東京勉強会#46 Azureセッション資料
わんくま東京勉強会#46 Azureセッション資料
 

More from Kouji Matsui

Making archive IL2C #6-55 dotnet600 2018
Making archive IL2C #6-55 dotnet600 2018Making archive IL2C #6-55 dotnet600 2018
Making archive IL2C #6-55 dotnet600 2018Kouji Matsui
 
Matrix signal controller and BrainPad overview
Matrix signal controller and BrainPad overviewMatrix signal controller and BrainPad overview
Matrix signal controller and BrainPad overviewKouji Matsui
 
What's Functional?
What's Functional?What's Functional?
What's Functional?Kouji Matsui
 
Pitfall for WioLTE
Pitfall for WioLTEPitfall for WioLTE
Pitfall for WioLTEKouji Matsui
 
How to make the calculator
How to make the calculatorHow to make the calculator
How to make the calculatorKouji Matsui
 
Write common, run anywhere
Write common, run anywhereWrite common, run anywhere
Write common, run anywhereKouji Matsui
 
Locality of Reference
Locality of ReferenceLocality of Reference
Locality of ReferenceKouji Matsui
 
Nespのコード生成
Nespのコード生成Nespのコード生成
Nespのコード生成Kouji Matsui
 
You will be assimilated. Resistance is futile.
You will be assimilated. Resistance is futile.You will be assimilated. Resistance is futile.
You will be assimilated. Resistance is futile.Kouji Matsui
 
How to meets Async and Task
How to meets Async and TaskHow to meets Async and Task
How to meets Async and TaskKouji Matsui
 
Beachhead implements new opcode on CLR JIT
Beachhead implements new opcode on CLR JITBeachhead implements new opcode on CLR JIT
Beachhead implements new opcode on CLR JITKouji Matsui
 
Async deepdive before de:code
Async deepdive before de:codeAsync deepdive before de:code
Async deepdive before de:codeKouji Matsui
 
Thread affinity and CPS
Thread affinity and CPSThread affinity and CPS
Thread affinity and CPSKouji Matsui
 
Async DeepDive basics
Async DeepDive basicsAsync DeepDive basics
Async DeepDive basicsKouji Matsui
 
continuatioN Linking
continuatioN LinkingcontinuatioN Linking
continuatioN LinkingKouji Matsui
 
真Intermediate languageのキホン
真Intermediate languageのキホン真Intermediate languageのキホン
真Intermediate languageのキホンKouji Matsui
 
.NET Coreから概観する.NETのOSSへの取り組み
.NET Coreから概観する.NETのOSSへの取り組み.NET Coreから概観する.NETのOSSへの取り組み
.NET Coreから概観する.NETのOSSへの取り組みKouji Matsui
 
Win32 APIをてなずけよう
Win32 APIをてなずけようWin32 APIをてなずけよう
Win32 APIをてなずけようKouji Matsui
 
式の体を成して無い式を式の体を成すように式と式木で何とかする式
式の体を成して無い式を式の体を成すように式と式木で何とかする式式の体を成して無い式を式の体を成すように式と式木で何とかする式
式の体を成して無い式を式の体を成すように式と式木で何とかする式Kouji Matsui
 

More from Kouji Matsui (20)

Making archive IL2C #6-55 dotnet600 2018
Making archive IL2C #6-55 dotnet600 2018Making archive IL2C #6-55 dotnet600 2018
Making archive IL2C #6-55 dotnet600 2018
 
Matrix signal controller and BrainPad overview
Matrix signal controller and BrainPad overviewMatrix signal controller and BrainPad overview
Matrix signal controller and BrainPad overview
 
Fun with BrainPad
Fun with BrainPadFun with BrainPad
Fun with BrainPad
 
What's Functional?
What's Functional?What's Functional?
What's Functional?
 
Pitfall for WioLTE
Pitfall for WioLTEPitfall for WioLTE
Pitfall for WioLTE
 
How to make the calculator
How to make the calculatorHow to make the calculator
How to make the calculator
 
Write common, run anywhere
Write common, run anywhereWrite common, run anywhere
Write common, run anywhere
 
Locality of Reference
Locality of ReferenceLocality of Reference
Locality of Reference
 
Nespのコード生成
Nespのコード生成Nespのコード生成
Nespのコード生成
 
You will be assimilated. Resistance is futile.
You will be assimilated. Resistance is futile.You will be assimilated. Resistance is futile.
You will be assimilated. Resistance is futile.
 
How to meets Async and Task
How to meets Async and TaskHow to meets Async and Task
How to meets Async and Task
 
Beachhead implements new opcode on CLR JIT
Beachhead implements new opcode on CLR JITBeachhead implements new opcode on CLR JIT
Beachhead implements new opcode on CLR JIT
 
Async deepdive before de:code
Async deepdive before de:codeAsync deepdive before de:code
Async deepdive before de:code
 
Thread affinity and CPS
Thread affinity and CPSThread affinity and CPS
Thread affinity and CPS
 
Async DeepDive basics
Async DeepDive basicsAsync DeepDive basics
Async DeepDive basics
 
continuatioN Linking
continuatioN LinkingcontinuatioN Linking
continuatioN Linking
 
真Intermediate languageのキホン
真Intermediate languageのキホン真Intermediate languageのキホン
真Intermediate languageのキホン
 
.NET Coreから概観する.NETのOSSへの取り組み
.NET Coreから概観する.NETのOSSへの取り組み.NET Coreから概観する.NETのOSSへの取り組み
.NET Coreから概観する.NETのOSSへの取り組み
 
Win32 APIをてなずけよう
Win32 APIをてなずけようWin32 APIをてなずけよう
Win32 APIをてなずけよう
 
式の体を成して無い式を式の体を成すように式と式木で何とかする式
式の体を成して無い式を式の体を成すように式と式木で何とかする式式の体を成して無い式を式の体を成すように式と式木で何とかする式
式の体を成して無い式を式の体を成すように式と式木で何とかする式
 

パターンでわかる! .NET Coreの非同期処理