MVC5で非同期を使用する利点は何ですか?


120

違いは何ですか:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

そして:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

MVCコードには非同期があるようですが、違いは何ですか。一方が他方よりもはるかに優れたパフォーマンスを提供しますか?どちらか一方の問題をデバッグする方が簡単ですか?アプリケーションが非同期を追加するように他のコントローラーを変更する必要がありますか?


大多数の状況では、MVCで非同期を使用しても大きなメリットはありませんが、多くの
欠点

1
@ChrisMarisic-最も深刻なものの1つ:ReaderWriterLockまたは他の同期プリミティブ(Semaphoreを除く)は使用できません。
Quarkly、

回答:


170

非同期アクションは、リモートサーバー呼び出しなどのI / Oバウンド操作を実行している場合にのみ役立ちます。非同期呼び出しの利点は、I / O操作中にASP.NETワーカースレッドが使用されないことです。最初の例が機能する方法は次のとおりです。

  1. 要求がアクションにヒットすると、ASP.NETはスレッドプールからスレッドを取得し、その実行を開始します。
  2. IdentityManager.Authentication.CheckPasswordAndSignInメソッドが呼び出されます。これはブロッキングコールです->コール全体でワーカースレッドが危険にさらされています。

次に、2番目の呼び出しの動作を示します。

  1. 要求がアクションにヒットすると、ASP.NETはスレッドプールからスレッドを取得し、その実行を開始します。
  2. IdentityManager.Authentication.CheckPasswordAndSignInAsyncすぐに返すと呼ばれています。I / O完了ポートが登録され、ASP.NETワーカースレッドがスレッドプールに解放されます。
  3. 後で操作が完了すると、I / O完了ポートが通知され、別のスレッドがスレッドプールから描画されて、ビューを返します。

2番目のケースでわかるように、ASP.NETワーカースレッドは短期間のみ使用されます。これは、他の要求を処理するためにプールで使用可能なスレッドがさらにあることを意味します。

結論として、内部に真の非同期APIがある場合にのみ、非同期アクションを使用します。非同期アクション内でブロッキング呼び出しを行うと、そのすべての利点が失われます。


コンテキスト同期についてはどうでしょう。これは、非同期アクションをまったく使用したくないほどのオーバーヘッドになりませんか?「実際に非同期で実行される非同期メソッドのオーバーヘッドは、SynchronizationContext.Postを使用してスレッドを切り替える必要があるかどうかに完全に依存します。そうする場合、オーバーヘッドは、再開時に実行するスレッド切り替えによって支配されます。つまり、現在のSynchronizationContextによって、大きな違いです。」(C#
5.0、2012の

1
@Darinなぜメインスレッドを解放することがそれほど重要なのですか?スレッドは制限されていますか?
Omtechguy 14

1
@Omtechguyより良いソリューションは、ASP.NET以外のリクエストをCDNに移動することです。単純なCDNは、JavaScriptや画像などの物理ファイルにサブドメインと個別のアプリプールを使用しているだけです。または、ファイルにNgineX / Lighttpd / Apacheを使用するか、Akamai(CDNを要求するが最も高価)などのサードパーティのサービスを使用することもできます
Chris Marisic

私はまだ混乱しています。ときCheckPasswordAndSignInAsyncに呼び出され、ASP.NETには、スレッドプールから別のスレッドを取り、それを実行を開始、それはしないのですか?そうでない場合、どこでchecking password procedure実行されますか?
KevinBui 2017

2

通常、単一のHTTP要求は単一のスレッドによって処理され、応答が返されるまでプールからそのスレッドを完全に削除します。TPLでは、この制約に拘束されません。入ってくる要求は、プール内の任意のスレッドで実行できる応答を計算するために必要な各計算単位で継続を開始します。このモデルを使用すると、標準のASP.Netよりもはるかに多くの同時要求を処理できます。

生成される新しいタスクであるかどうか、および待機する必要があるかどうか。常に約70 msの70ミリ秒を考えてください。マックス。メソッド呼び出しにかかる時間。それより長い場合、UIはおそらく非常に応答性を感じません。


0

起動時に多数の同時要求が発生するか、バースト性のある負荷(同時実行性が突然増加する)があるWebアプリケーションでは、これらのWebサービス呼び出しを非同期にすると、アプリケーションの応答性が向上します。非同期リクエストは、同期リクエストと同じ時間で処理されます。たとえば、リクエストが完了するまでに2秒を必要とするWebサービスの呼び出しを行った場合、同期または非同期のどちらで実行されても、リクエストには2秒かかります。ただし、非同期呼び出しの間、スレッドは、最初の要求が完了するのを待つ間、他の要求への応答をブロックされません。したがって、非同期リクエストは、長時間実行オペレーションを呼び出す同時リクエストが多数ある場合に、リクエストキューイングとスレッドプールの増加を防ぎます。


aspnetアプリケーションが主に他のWebサーバーへの呼び出しで構成されている場合、主に「ゲートウェイ」/「プロキシ」として動作しており、非同期はその目的に役立ちます。
Chris Marisic、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.