回答:
非同期アクションメソッドは、アクションがいくつかの独立した長時間実行オペレーションを実行する必要がある場合に役立ちます。
AsyncControllerクラスの一般的な用途は、長時間実行されるWebサービスの呼び出しです。
データベース呼び出しを非同期にする必要がありますか?
IISスレッドプールは、多くの場合、データベースサーバーよりも多くの同時ブロッキング要求を処理できます。データベースがボトルネックである場合、非同期呼び出しはデータベースの応答を高速化しません。スロットルメカニズムがなければ、非同期呼び出しを使用して、圧倒されたデータベースサーバーにさらに多くの作業を効率的にディスパッチしても、データベースへの負担が増えるだけです。DBがボトルネックである場合、非同期呼び出しは特効薬ではありません。
@PanagiotisKanavosのコメントから派生:
さらに、非同期は並列を意味しません。非同期実行により、貴重なスレッドプールスレッドが外部リソースのブロックから解放され、複雑さやパフォーマンスコストが発生しません。これは、同じIISマシンがより多くの同時要求を処理できることを意味します。
また、ブロッキング呼び出しは、CPUを集中的に使用するスピンウェイトで始まることも考慮する必要があります。ストレス時に、呼び出しをブロックすると、遅延の増大とアプリプールのリサイクルが発生します。非同期呼び出しは単にこれを回避します
この件に関する私のMSDNの記事が参考になります。この記事ではasync
、ASP.NETでの使用方法だけでなく、ASP.NETでいつ使用すべきかを説明するためasync
に多くのスペースを取った。
ASP.NET MVCで非同期アクションを使用するいくつかの懸念があります。アプリのパフォーマンスが向上する場合とそうでない場合
まず、async
/ await
はスレッドを解放することのすべてであることを理解してください。GUIアプリケーションでは、主にGUIスレッドを解放してユーザーエクスペリエンスを向上させることを目的としています。サーバーアプリケーション(ASP.NET MVCを含む)では、主に要求スレッドを解放してサーバーをスケーリングできるようにします。
特に、それはしません:
await
。await
ブラウザーではなく、ASP.NETスレッドプールにのみ「委譲」します。最初の質問は、ASP.NET MVCのあらゆる場所で非同期アクションを使用するのは良いことですか?
I / Oを行うすべての場所で使用するのが良いと思います。ただし、必ずしも有益であるとは限りません(以下を参照)。
しかし、それはだ、悪い CPUバウンドメソッドのためにそれを使用します。開発者は、コントローラーをasync
呼び出すだけでメリットを得ることができると考える場合がありますがTask.Run
、これは恐ろしい考えです。そのコードは、別のスレッドを使用することによって要求スレッドを解放することになるため、まったくメリットがありません(実際、追加のスレッドスイッチのペナルティを取っています)。
(EF / NHibernate /その他のORMを介して)データベースにクエリを実行する場合、async / awaitキーワードを使用する必要がありますか?
利用可能な待機可能なメソッドを使用できます。現在、主要なプレーヤーのほとんどがサポートasync
していますが、サポートしていないものもあります。ORMがをサポートしていない場合はasync
、それをTask.Run
そのようなものでラップしようとしないでください(上記を参照)。
「使用できます」と言ったことに注意してください。単一のデータベースバックエンドを備えたASP.NET MVCについて話している場合、(ほぼ確実に)からスケーラビリティのメリットを得ることはできませんasync
。これは、IISがSQLサーバー(または他の従来のRDBMS)の単一のインスタンスよりもはるかに多くの同時要求を処理できるためです。ただし、SQLサーバークラスター、Azure SQL、NoSQLなど、バックエンドがよりモダンであり、バックエンドがスケーリング可能で、スケーラビリティのボトルネックがIISである場合、からスケーラビリティのメリットを得ることができますasync
。
3番目の質問-待機キーワードを使用して、1つの単一アクションメソッドでデータベースに非同期でクエリを何回実行できますか?
好きなだけ。ただし、多くのORMには接続ごとに1つの操作のルールがあることに注意してください。特に、EFはDbContextごとに1つの操作のみを許可します。これは、操作が同期か非同期かに関係なく当てはまります。
また、バックエンドのスケーラビリティについても念頭に置いてください。SQL Serverの単一インスタンスを使用していて、IISがSQLServerをフル稼働に保つことができる場合、SQLServerへのプレッシャーを2倍または3倍にしても、まったく役に立たないでしょう。
ASP.NET MVCのどこでも非同期アクションを使用するのは良いことですか?
プログラミングでいつものように、それは依存します。特定の道を行くときは常にトレードオフがあります。
async-await
サービスへの同時リクエストを受信することがわかっていて、適切にスケールアウトできるようにしたい場合に最適です。async-await
スケールアウトにどのように役立ちますか?ネットワーク呼び出しやデータベースのヒットなど、非同期IO呼び出しを同期的に呼び出すと、実行を担当する現在のスレッドは、要求が完了するのを待ってブロックされます。を使用async-await
すると、フレームワークがステートマシンを作成できるようになります。これにより、IO呼び出しが完了した後、中断したところからメソッドが実行を継続します。
注意すべき点は、この状態マシンにはわずかなオーバーヘッドがあることです。メソッドを非同期にしても、実行が速くなるわけではありません。これは、多くの人が理解している誤解や誤解の重要な要素です。
使用時に考慮すべきもう1つのことasync-await
は、それが完全に非同期であるという事実です。つまり、非同期がコールスタック全体を突き抜けて、buttomに到達することがわかります。つまり、同期APIを公開したい場合、非同期と同期がうまく混ざらないため、特定の量のコードが重複することがよくあります。
(EF / NHibernate /その他のORMを介して)データベースにクエリを実行する場合、async / awaitキーワードを使用する必要がありますか?
非同期IO呼び出しを使用する方法を選択する場合は、はい、それasync-await
が適切な選択肢になります。最新のデータベースプロバイダーがTAP(タスク非同期パターン)を実装する非同期メソッドを公開しているためです。
awaitキーワードを使用して、1つの単一アクションメソッドでデータベースを非同期にクエリできる回数は何回ですか?
データベースプロバイダーによって指定されたルールに従う限り、必要な数だけ使用できます。非同期呼び出しの数に制限はありません。互いに独立していて同時に実行できるクエリがある場合、それぞれに対して新しいタスクをスピンし、を使用await Task.WhenAll
して両方が完了するのを待つことができます。
scale out well
が意味するかもしれないことを理解しないでしょうyour server won't die under load
。または、それが原因である可能性がありますonce burned ...
私の5セント:
async/await
DBや外部サービスWebサービスなどのIO操作を行う場合にのみ使用します。PSポイント1には例外的なケースがありますが、そのためには非同期内部について十分に理解している必要があります。
追加の利点として、必要に応じていくつかのIO呼び出しを並行して実行できます。
Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result
async
アクションは、アクションがDBまたはネットワークバインドされた呼び出しに対していくつかのI \ O操作を行うときに最も役立ちます。ここで、要求を処理するスレッドは、呼び出したDBまたはネットワークバインドされた呼び出しから応答を受け取る前に停止します。それらと一緒にawaitを使用することをお勧めします。これにより、アプリケーションの応答性が大幅に向上します(DBまたはそのような他の操作の待機中にストールするASP入出力スレッドが少なくなるため)。私のすべてのアプリケーションでは、DBへの多くの呼び出しが非常に必要なときはいつでも、それらを常にawaiatableメソッドでラップし、それをawait
キーワードで呼び出しました。
ご存じのとおり、MVCは非同期コントローラーをサポートしているので、それを利用する必要があります。コントローラーが長い操作を実行する場合(ディスクベースのI / Oまたは別のリモートサービスへのネットワーク呼び出しなど)、要求が同期的に処理されると、IISスレッドは常にビジー状態になります。その結果、スレッドは時間のかかる操作が完了するのを待っているだけです。最初に要求された操作の進行中に他の要求を処理することで、より効果的に利用できます。これにより、より多くの同時リクエストに対応できます。Webサービスは非常にスケーラブルであり、C10kの問題に簡単に遭遇することはありません。dbクエリにはasync / awaitを使用することをお勧めします。はい、必要に応じて何度でも使用できます。
私の経験では、今日、多くの開発者async/await
がコントローラーのデフォルトとして使用しています。
私の提案は、それがあなたを助けることがわかっているときだけそれを使うことです。
その理由は、Stephen Clearyや他の人がすでに述べたように、解決するのではなく、パフォーマンスの問題を引き起こす可能性があり、特定のシナリオでのみ役立つ場合があるためです。
ASP.NET MVCのどこでも非同期アクションを使用するのは良いことですか?
特に、大量のデータと計算操作で発生するワーカープロセスレベルでパフォーマンスの問題が発生している場合は、非同期メソッドを使用できる場所にそうすることをお勧めします。それ以外の場合は、単体テストでキャストが必要になるため不要です。
待機可能なメソッドについて:(EF / NHibernate /その他のORMを介して)データベースにクエリを実行する場合は、async / awaitキーワードを使用する必要がありますか?
はい。ワーカープロセスレベルでのパフォーマンスの問題を回避するために、DB操作にはできるだけ非同期を使用することをお勧めします。EFは、次のようなほとんどの操作に対して多くの非同期の代替手段を作成していることに注意してください。
.ToListAsync()
.FirstOrDefaultAsync()
.SaveChangesAsync()
.FindAsync()
awaitキーワードを使用して、単一のアクションメソッドでデータベースに非同期でクエリを何度実行できますか?
空は限界です