ASP.NET MVC で非同期コントローラーを使用する必要があるのはいつですか?

このテーマに関する私の MSDN 記事が参考になるかもしれません。その記事では、いつすべきかを説明するために多くのスペースを取りました async を使用 方法だけでなく、ASP.NET で async を使用する ASP.NET で。

まず、async を理解する /await スレッドを解放することがすべてです . GUI アプリケーションでは、主に GUI スレッドを解放する ことです。 ユーザーエクスペリエンスが向上します。サーバー アプリケーション (ASP.NET MVC を含む) では、主にリクエスト スレッドを解放することです。 サーバーがスケーリングできるようにします。

特に、しない:

  • 個々のリクエストをより迅速に完了する。実際、完了するのは (少しだけ) 遅くなります。
  • await にヒットしたら呼び出し元/ブラウザに戻ります . await ブラウザではなく、ASP.NET スレッド プールにのみ "譲歩" します。

I/O を行っているあらゆる場所で使用するのが良いと思います。必ずしも有益ではないかもしれません 、ただし (以下を参照)。

ただし、悪い CPU バウンドのメソッドに使用します。 async のメリットが得られると考える開発者もいます。 Task.Run を呼び出すだけで これは恐ろしい考えです。そのコードは別のスレッドを使用してリクエスト スレッドを解放することになるため、何のメリットもありません (実際、余分なスレッド切り替えのペナルティを受けています)!

利用可能な待機可能なメソッドを使用できます。現在、主要なプレーヤーのほとんどが async をサポートしています 、しかしそうでないものもいくつかあります。 ORM が async をサポートしていない場合 、それを Task.Run でラップしようとしないでください またはそのようなもの (上記参照)。

私が「あなたはできます」と言ったことに注意してください 単一のデータベース バックエンドを持つ ASP.NET MVC について話している場合、(ほぼ確実に) async からスケーラビリティの利点を得ることはできません。 .これは、IIS が SQL サーバー (または他の従来の RDBMS) の単一インスタンスよりもはるかに多くの同時要求を処理できるためです。ただし、バックエンドがより最新のもの (SQL サーバー クラスター、Azure SQL、NoSQL など) であり、バックエンドがスケーリング可能であり、スケーラビリティのボトルネックが IIS である場合は、 async からスケーラビリティの利点を得ることができます .

好きなだけ。ただし、多くの ORM には、接続ごとに 1 つの操作の規則があることに注意してください。特に、EF では DbContext ごとに 1 つの操作のみが許可されます。これは、操作が同期であるか非同期であるかに関係なく当てはまります。

また、バックエンドのスケーラビリティにも注意してください。 SQL Server の 1 つのインスタンスにアクセスしていて、IIS が既に SQLServer をフル キャパシティで維持できる場合、SQLServer へのプレッシャーを 2 倍または 3 倍にしても、まったく役に立ちません。


非同期アクション メソッドは、アクションが複数の独立した長時間実行操作を実行する必要がある場合に役立ちます。

データベース呼び出しは非同期にする必要がありますか?

IIS スレッド プールは、多くの場合、データベース サーバーよりも多くの同時ブロック要求を処理できます。データベースがボトルネックである場合、非同期呼び出しによってデータベースの応答が高速化されることはありません。スロットリング メカニズムがなければ、非同期呼び出しを使用して負荷の高いデータベース サーバーにより多くの作業を効率的にディスパッチしても、データベースへの負担が増えるだけです。 DB がボトルネックである場合、非同期呼び出しは特効薬にはなりません。

すべき 1 と 2 の参照を見てください

@PanagiotisKanavos コメントから派生:


プログラミングではいつものように、依存する .特定の道を進むときは常にトレードオフがあります。

async-await サービスへの同時リクエストを受け取ることがわかっていて、スケールアウトできるようにしたい場所で輝きます。 良い。 async-await はどのように機能しますか スケールアウトに役立ちますか?非同期IO呼び出しを同期的に呼び出すと、 ネットワーク呼び出しやデータベースへのヒットなど、実行を担当する現在のスレッドは、リクエストが完了するのを待ってブロックされます。 async-await を使用する場合 、フレームワークがステート マシンを作成できるようにします。これにより、IO 呼び出しが完了した後、メソッドが中断したところから実行を継続できるようになります。

注意すべきことは、このステート マシンには微妙なオーバーヘッドがあるということです。メソッドを非同期にしても実行速度は速くなりません 、そしてそれは理解すべき重要な要素であり、多くの人が持っている誤解です.

async-await を使用する際に考慮すべきもう 1 つのこと ずっと非同期であるという事実です つまり、async がコール スタック全体に上から下に浸透するのがわかります。これは、同期 API を公開したい場合、async と sync がうまく混ざり合わないため、特定の量のコードを複製していることに気付くことが多いことを意味します。

非同期 IO 呼び出しを使用することを選択した場合は、はい、async-await 最近のデータベース プロバイダーは、TAP (タスク非同期パターン) を実装する非同期メソッドを公開するようになっているため、良い選択です。

データベース プロバイダーの規定に従っている限り、必要な数だけ。実行できる非同期呼び出しの量に制限はありません。互いに独立していて同時に作成できるクエリがある場合は、それぞれに対して新しいタスクをスピンして await Task.WhenAll を使用できます 両方が完了するまで待ちます。