第2章. 非同期の基本
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
このの章では、async とawait を使った非同期操作の基本を紹介する。ここでは、HTTPリクエスト、データベースコマンド、Webサービス呼び出しなどの演算子である、当然の非同期操作のみを扱う。
CPU負荷の高い演算子を非同期のように扱いたい場合(UIスレッドをブロックしないようにするなど)は、第4章と レシピ8.4を参照のこと。イベントのストリームを処理する必要がある場合は、第3章と第6章を参照のこと。
2.1 一時停止する
問題
(非同期で)一定時間待つ必要がある。これは単体テストや再試行遅延を実装するときによくあるシナリオだ。また、単純なタイムアウトをコーディングするときにも出てくる。
解決策
Task 型には、指定された時間後に完了するタスクを返す静的メソッドDelay がある。
以下のコード例では、非同期に完了するタスクを定義している。非同期演算子を偽装する場合、同期的成功と非同期的成功、そして非同期的失敗をテストすることが重要である。以下の例では、非同期成功のケースで使われるタスクを返している:
asyncTask<T>DelayResult<T>(Tresult,TimeSpandelay){awaitTask.Delay(delay);returnresult;}
Exponentialbackoffは、再試行間の遅延を増やす戦略である。再試行でサーバが溢れないようにするために、ウェブサービスを扱うときに使用する。次の例は、指数バックオフの簡単な実装である:
asyncTask<string>DownloadStringWithRetries(HttpClientclient,stringuri){// Retry after 1 second, then after 2 seconds, then 4.TimeSpannextDelay=TimeSpan.FromSeconds(1);for(inti=0;i!=3;++i){try{returnawaitclient.GetStringAsync(uri);}catch{}awaitTask.Delay(nextDelay);nextDelay=nextDelay+nextDelay;}// Try one last time, allowing the error to propagate.returnawaitclient.GetStringAsync(uri);}
チップ
、プロダクション・コードには、NuGetライブラリーのような、より徹底したソリューションをお勧めする。 Pollyこのコードは、Task.Delay の簡単な使用例に過ぎない。
Task.Delay を単純なタイムアウトとして使うこともできる。CancellationTokenSource はタイムアウトの実装に使われる通常の型である(レシピ10.3)。キャンセル・トークンを無限Task.Delay 、指定した時間後にキャンセルするタスクを提供する。最後に、そのタイマー・タスクをTask.WhenAny (レシピ2.5)と一緒に使って、"ソフト・タイムアウト "を実装する。以下のコード例は、サービスが3秒以内に応答しない場合、 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access