ASP.NET MVCの非同期コントローラー:真の利点/達成方法


12

私はASP.NET MVCの非同期コントローラーメソッドに関する記事(http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx)を通して取り組んできました。ポイントが足りないかもしれません。

私が書いたこの方法を考えてみましょう。これは、記事の例に非常によく似ています。

[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
    WidgetPageViewModel model = new WidgetPageViewModel()
    {
        toAdd = new Widget()
    };
    model.all = await _repo.GetAllAsync(cancellationToken);
    return View(model);
}

私は物事を理解しているので、これは物事が実行時に展開する方法です:

  1. 着信HTTP要求に対してASP.NETスレッドが作成されます。

  2. このスレッドは(おそらく何らかの必要な準備作業を行った上で)上記のIndex()メソッドに入ります。

  3. 実行は「await」キーワードに到達し、別のスレッドでデータ取得プロセスを開始します。

  4. 元の「ASP.NET」スレッドは、戻り値としてTaskクラスのインスタンスを使用して、ハンドラーメソッドを呼び出したコードに戻ります。

  5. ハンドラーメソッドを呼び出したインフラストラクチャコードは、実際のActionResultオブジェクトを使用する必要があるポイントに到達するまで(ページのレンダリングなど)、元の "ASP.NET"スレッドで動作し続けます。

  6. 次に、呼び出し元はTask.Resultメンバーを使用してこのオブジェクトにアクセスします。これにより、上記の手順3で暗黙的に作成されたスレッドを待機します(つまり、「ASP.NET」スレッド)。

私が些細なことだと思う2つのことを除いて、await / asyncなしで同じことと比較してこれが何を達成するのか見ていません:

  • 呼び出し側スレッドとawaitによって作成されたワーカースレッドは、一定の期間(上記の#5の「まで」)並行して動作できます。私の考えでは、その期間はかなり短いです。インフラストラクチャがコントローラーメソッドを呼び出す場合、それが(もしあれば)さらに多くのことができるようになる前に、通常はコントローラー呼び出しの実際のActionResultが必要だと考えています。

  • 長時間実行される非同期コントローラー操作のタイムアウトとキャンセルに関連するいくつかの有用な新しいインフラストラクチャがあります。

非同期コントローラーメソッドを追加する目的は、ASP.NETワーカースレッドを解放して、実際にHTTP要求に応答することです。これらのスレッドは有限のリソースです。残念ながら、記事で提案されているパターンが実際にこれらのスレッドを節約するのにどのように役立つかはわかりません。そして、それが何らかの形でリクエストを処理する負担を何らかの非ASP.NETスレッドにオフロードしても、それは何を達成しますか?たまたまHTTP要求を処理できるスレッドは、一般のスレッドとは大きく異なりますか?


Execution will reach the "await" keyword and kick off a data acquisition process on another thread - 必ずしも。 async別のスレッドを必要としません...それは継続です。同じスレッドで
ロバートハーヴェイ


「実行はawaitキーワードに到達し、別のスレッドでデータ取得プロセスを開始します。」あなたはこれを逆方向に取得しました:待っているのはそれが戻ってくるときです。GetAllAsync()の結果を変数に保存し、代わりにそれを待ち、それがより明確になるかどうかを確認するために、それを分割してみてください。
エスベンスコフペダーセン

回答:


9

Task Parallel Library(TPL)を使用しないASP.Netは、スレッドプール内のスレッドの数によって、同時に処理できるリクエストの数が制限されています。TPLを使用するASP.Netは、要求を処理するマシンのCPU /メモリ/ IOによって制限されます。

Task Parallel Library(TPL)は、あなたが思うようにスレッドを消費しません。タスクはスレッドではなく、ある計算単位のラッパーです。タスクスケジューラは、ビジーでないスレッドで各タスクを実行します。実行時、タスクの待機はスレッドをブロックせず、実行状態を保留するだけで、後から続行できます。

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


では、ASP.NETスレッドはいつプールに返されますか?「await」キーワードがヒットしたとき
user1172763

async / await + TPLを使用すると、コンパイラはコードをタスクスケジューラによって実行される独立した計算ユニットに分割できます。タスクスケジューラに実行できるタスクがなくなって、スレッドがそれに与えられた作業を完了すると、スレッドは概念的にプールに返されます。
モルタラペマン

これは概念的には正しく、おそらく有用な答えです...しかし、現実はスレッドの俊敏性のために少し複雑です。
ジョン・ウー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.