[解決済み] 複数のタスクにasync/awaitを使用する
2022-02-24 05:04:16
質問内容
完全に非同期のAPIクライアントを使っています。
Task
または
Task<T>
は、例えば
static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}
C# 5 の async/await 演算子を使用して、複数のタスクを開始し、それらのすべてが完了するのを待つための、正しい/最も効率的な方法は何ですか。
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
または
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
APIクライアントは内部でHttpClientを使っているので、すぐに5つのHTTPリクエストを発行し、それぞれのリクエストが完了するたびにコンソールに書き込むと思います。
どのように解決するのですか?
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
上記のコードで操作を並列に実行していますが、このコードでは各操作が実行されるスレッドをブロックしています。例えば、ネットワーク呼び出しに2秒かかるとすると、各スレッドは2秒間何もせずに待ちます。
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
一方、上記のコードに
WaitAll
もスレッドをブロックしてしまうので、その処理が終わるまでスレッドは他の処理をすることができません。
推奨するアプローチ
私は
WhenAll
を使えば、Parallelで非同期的に処理を実行することができます。
public async Task DoWork() {
int[] ids = new[] { 1, 2, 3, 4, 5 };
await Task.WhenAll(ids.Select(i => DoSomething(1, i, blogClient)));
}
実は、上記の場合にも
await
連続性がないため、メソッドから直接リターンすることができます。public Task DoWork() { int[] ids = new[] { 1, 2, 3, 4, 5 }; return Task.WhenAll(ids.Select(i => DoSomething(1, i, blogClient))); }
このことを裏付けるために、以下のブログ記事で、すべての そのメリット・デメリットをご紹介します。 ASP.NET Web APIによる非同期I/Oの並行処理の方法と場所
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] usingディレクティブはネームスペースの内側と外側のどちらを使うべきですか?
-
[解決済み] forEachループでasync/awaitを使用する
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] 非同期Task<T>メソッドを同期的に実行するにはどうしたらいいですか?
-
[解決済み] C#でawaitを使わずに非同期メソッドを安全に呼び出す方法
-
[解決済み] await/asyncを使用しているときにHttpClient.GetAsync(...)が返らない
-
[解決済み】複数の非同期タスクを実行し、すべてのタスクが完了するのを待つ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない