Ich habe einen Artikel über asynchrone Controller-Methoden in ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx ) durchgearbeitet und denke Ich kann den Punkt verfehlen.
Betrachten Sie diese Methode, die ich geschrieben habe und die einem Beispiel aus dem Artikel sehr ähnlich ist:
[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);
}
So wie ich die Dinge verstehe, werden sich die Dinge zur Laufzeit folgendermaßen entwickeln:
Für eine eingehende HTTP-Anforderung wird ein ASP.NET-Thread erstellt.
Dieser Thread wird (nachdem er vermutlich einige notwendige Vorarbeiten durchgeführt hat) in meine Index () -Methode oben eingegeben.
Die Ausführung erreicht das Schlüsselwort "await" und startet einen Datenerfassungsprozess in einem anderen Thread.
Der ursprüngliche "ASP.NET" -Thread kehrt zu dem Code zurück, der meine Handlermethode aufgerufen hat, mit einer Instanz der Klasse Task als Rückgabewert.
Der Infrastrukturcode, der meine Handler-Methode aufgerufen hat, wird weiterhin auf dem ursprünglichen "ASP.NET" -Thread ausgeführt, bis er einen Punkt erreicht, an dem das eigentliche ActionResult-Objekt verwendet werden muss (z. B. zum Rendern der Seite).
Der Aufrufer greift dann mit dem Task.Result-Member auf dieses Objekt zu, wodurch es (dh der "ASP.NET" -Thread) auf den in Schritt 3 implizit erstellten Thread wartet.
Ich sehe nicht, was dies im Vergleich zu derselben Sache ohne Warten / Asynchronisieren bewirkt, abgesehen von zwei Dingen, die ich als unbedeutend empfinde:
Der Aufruferthread und der von await erstellte Arbeitsthread können einige Zeit parallel arbeiten (der "bis" -Teil von # 5 oben). Meine Vermutung ist, dass der Zeitraum ziemlich klein ist. Wenn die Infrastruktur eine Controller-Methode aufruft, benötigt sie meiner Meinung nach im Allgemeinen das eigentliche ActionResult des Controller-Aufrufs, bevor sie viel (wenn überhaupt) mehr kann.
Es gibt einige hilfreiche neue Infrastrukturen, die sich auf das Timeout und das Abbrechen lang laufender asynchroner Controller-Vorgänge beziehen.
Der Zweck des Hinzufügens von asynchronen Controller-Methoden besteht angeblich darin, diese ASP.NET-Arbeitsthreads freizugeben, um tatsächlich HTTP-Anforderungen zu beantworten. Diese Threads sind eine endliche Ressource. Leider sehe ich nicht, wie das im Artikel vorgeschlagene Muster tatsächlich dazu dient, diese Threads zu erhalten. Und selbst wenn dies der Fall ist und die Last der Bearbeitung der Anforderung auf einen Nicht-ASP.NET-Thread verlagert, was bringt das? Unterscheiden sich Threads, die eine HTTP-Anforderung verarbeiten können, stark von Threads im Allgemeinen?
Execution will reach the "await" keyword and kick off a data acquisition process on another thread
-- Nicht unbedingt.async
benötigt keinen weiteren Thread ... Es ist eine Fortsetzung. Dies kann erreicht werden, indem Anweisungen für denselben Thread neu angeordnet werden.