Kontrolery asynchroniczne w ASP.NET MVC: prawdziwe zalety / jak osiągnięte?

12

Pracowałem nad artykułem na temat metod kontrolera asynchronicznego w ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx ) i myślę, że Mogę nie rozumieć o co chodzi.

Rozważ tę metodę, którą napisałem, która jest bardzo podobna do przykładu z artykułu:

[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);
}

Jak rozumiem, w ten sposób rzeczy będą się rozwijać w czasie wykonywania:

  1. Wątek ASP.NET zostanie utworzony dla przychodzącego żądania HTTP.

  2. Wątek ten (prawdopodobnie wykonując niezbędne prace wstępne) wprowadzi moją metodę Index () powyżej.

  3. Wykonanie osiągnie słowo kluczowe „Oczekiwanie” i rozpocznie proces akwizycji danych w innym wątku.

  4. Oryginalny wątek „ASP.NET” powróci do kodu, który wywołał moją metodę obsługi, z instancją klasy Task jako wartością zwracaną.

  5. Kod infrastruktury, który wywołał moją metodę obsługi, będzie kontynuował działanie w oryginalnym wątku „ASP.NET”, dopóki nie osiągnie punktu, w którym będzie musiał użyć rzeczywistego obiektu ActionResult (np. Do renderowania strony).

  6. Wywołujący uzyska następnie dostęp do tego obiektu za pomocą elementu Task.Result, co spowoduje, że (tj. Wątek „ASP.NET”) zaczeka na wątek utworzony pośrednio w kroku 3 powyżej.

Nie widzę, co to osiąga w porównaniu do tej samej rzeczy bez oczekiwania / asynchronizacji, z wyjątkiem dwóch rzeczy, które postrzegam jako drobne:

  • Wątek wywołujący i wątek roboczy utworzony przez Oczekuj mogą działać równolegle przez pewien okres czasu (część „do” w punkcie 5 powyżej). Mam przeczucie, że okres czasu jest dość krótki. Kiedy infrastruktura wywołuje metodę kontrolera, myślę, że generalnie potrzebuje rzeczywistego ActionResult wywołania kontrolera, zanim będzie w stanie zrobić więcej (jeśli cokolwiek) więcej.

  • Istnieje pewna nowa pomocna infrastruktura związana z przekroczeniem limitu czasu i anulowaniem długotrwałych operacji kontrolera asynchronicznego.

Dodanie metod kontrolera asynchronicznego ma na celu zwolnienie wątków roboczych ASP.NET w celu rzeczywistego odpowiadania na żądania HTTP. Te wątki są ograniczonym zasobem. Niestety nie widzę, jak wzorzec sugerowany w tym artykule faktycznie służy do zachowania tych wątków. A nawet jeśli tak, i w jakiś sposób odciąża obsługę żądania do wątku innego niż ASP.NET, co to osiąga? Czy wątki, które są w stanie obsłużyć żądanie HTTP, znacznie różnią się od wątków w ogóle?

użytkownik1172763
źródło
Execution will reach the "await" keyword and kick off a data acquisition process on another thread-- Niekoniecznie. asyncnie wymaga kolejnego wątku ... To kontynuacja. Można tego dokonać, zmieniając instrukcje w tym samym wątku.
Robert Harvey
Więcej informacji tutaj: msdn.microsoft.com/en-us/library/hh191443.aspx
Robert Harvey
„Wykonanie osiągnie oczekiwane słowo kluczowe i rozpocznie proces akwizycji danych w innym wątku.” masz to odwrotnie: czekasz, kiedy wróci. Spróbuj go podzielić, aby zapisać wynik z GetAllAsync () w zmiennej i poczekać na to zamiast tego i zobaczyć, czy stanie się bardziej przejrzysty.
Esben Skov Pedersen

Odpowiedzi:

9

Program ASP.Net, który nie korzysta z biblioteki zadań równoległych (TPL), ma ograniczoną liczbę żądań, które może obsłużyć jednocześnie, przez liczbę wątków w puli wątków. ASP.Net korzystający z licencji TPL jest ograniczony przez procesor / pamięć / IO żądań obsługi maszyny.

Biblioteka zadań równoległych (TPL) nie wykorzystuje wątków w sposób, w jaki wydaje się, że tak. Zadania nie są wątkami, są otoczeniem pewnej jednostki obliczeniowej. Harmonogram zadań jest odpowiedzialny za wykonanie każdego zadania w dowolnym wątku, który nie jest zajęty. W czasie wykonywania oczekiwanie na zadanie nie blokuje wątku, jedynie parkuje stan wykonania, aby można było kontynuować w późniejszym czasie.

Zwykle pojedyncze żądanie HTTP byłoby obsługiwane przez pojedynczy wątek, całkowicie usuwając ten wątek z puli, dopóki nie zostanie zwrócona odpowiedź. Dzięki licencji TPL nie jesteś związany tym ograniczeniem. Każde przychodzące żądanie rozpoczyna ciąg dalszy od każdej jednostki obliczeniowej wymaganej do obliczenia odpowiedzi zdolnej do wykonania w dowolnym wątku w puli. Za pomocą tego modelu można obsłużyć o wiele więcej równoczesnych żądań niż w standardowym programie ASP.Net.

śmiertelnik
źródło
Kiedy wątek ASP.NET zostanie zwrócony do puli? Kiedy trafi słowo kluczowe „czekaj”?
user1172763,
async / oczekuj + TPL pozwala kompilatorowi podzielić kod na niezależne jednostki obliczeniowe, które są wykonywane przez harmonogram zadań. Wątek jest koncepcyjnie zwracany do puli, gdy w harmonogramie zadań nie ma już zadań do wykonania, a wątek kończy powierzone mu zadanie.
mortalapeman
Jest to poprawne koncepcyjnie i prawdopodobnie przydatna odpowiedź ... jednak rzeczywistość jest nieco bardziej skomplikowana ze względu na zwinność wątku .
John Wu