私は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);
}
私は物事を理解しているので、これは物事が実行時に展開する方法です:
着信HTTP要求に対してASP.NETスレッドが作成されます。
このスレッドは(おそらく何らかの必要な準備作業を行った上で)上記のIndex()メソッドに入ります。
実行は「await」キーワードに到達し、別のスレッドでデータ取得プロセスを開始します。
元の「ASP.NET」スレッドは、戻り値としてTaskクラスのインスタンスを使用して、ハンドラーメソッドを呼び出したコードに戻ります。
ハンドラーメソッドを呼び出したインフラストラクチャコードは、実際のActionResultオブジェクトを使用する必要があるポイントに到達するまで(ページのレンダリングなど)、元の "ASP.NET"スレッドで動作し続けます。
次に、呼び出し元は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
別のスレッドを必要としません...それは継続です。同じスレッドで