Metody akcji asynchronicznej są użyteczne, gdy akcja musi wykonać kilka niezależnych długich operacji.
Typowym zastosowaniem klasy AsyncController są długotrwałe wywołania usługi sieci Web.
Czy moje połączenia z bazą danych powinny być asynchroniczne?
Pula wątków IIS często może obsłużyć o wiele więcej jednoczesnych żądań blokowania niż serwer bazy danych. Jeśli baza danych stanowi wąskie gardło, wywołania asynchroniczne nie przyspieszą odpowiedzi bazy danych. Bez mechanizmu dławienia efektywne wysyłanie większej ilości pracy do przytłoczonego serwera bazy danych za pomocą wywołań asynchronicznych po prostu przenosi większe obciążenie bazy danych. Jeśli twoje DB jest wąskim gardłem, asynchroniczne połączenia nie będą magiczną kulą.
Ci powinni przyjrzeć się 1 i 2 referencje
Pochodzi z komentarzy @PanagiotisKanavos:
Ponadto asynchronizacja nie oznacza równoległości. Wykonanie asynchroniczne uwalnia cenny wątek puli wątków od blokowania zasobu zewnętrznego, bez komplikacji i kosztów wydajności. Oznacza to, że ta sama maszyna IIS może obsłużyć więcej jednoczesnych żądań, a nie że będzie działać szybciej.
Należy również wziąć pod uwagę, że blokowanie połączeń zaczyna się od intensywnego oczekiwania CPU. W okresach stresu blokowanie połączeń spowoduje eskalację opóźnień i ponowne wykorzystanie puli aplikacji. Połączenia asynchroniczne po prostu tego unikają
Pomocny może być mój artykuł MSDN na ten temat ; W tym artykule poświęciłem dużo miejsca opisując, kiedy powinieneś używać
async
na ASP.NET, a nie tylko jak używaćasync
na ASP.NET.Po pierwsze, zrozum, że
async
/await
dotyczy uwolnienia wątków . W aplikacjach GUI chodzi przede wszystkim o zwolnienie wątku GUI, aby wygoda użytkownika była lepsza. W aplikacjach serwerowych (w tym ASP.NET MVC) chodzi głównie o zwolnienie wątku żądania, aby serwer mógł się skalować.W szczególności nie będzie:
await
.await
„ustępuje” tylko puli wątków ASP.NET, a nie przeglądarce.Powiedziałbym, że dobrze jest używać go wszędzie tam, gdzie robisz operacje wejścia / wyjścia. Jednak niekoniecznie może być korzystne (patrz poniżej).
Jednak źle jest używać go do metod związanych z procesorem. Czasami deweloperzy myślą, że mogą czerpać korzyści,
async
po prostu dzwoniącTask.Run
do kontrolerów, a to jest okropny pomysł. Ponieważ ten kod ostatecznie zwalnia wątek żądania przez zajęcie innego wątku, więc nie ma żadnej korzyści (i w rzeczywistości ponoszą karę za dodatkowe przełączanie wątków)!Możesz użyć wszelkich dostępnych metod. Obecnie większość głównych graczy obsługuje
async
, ale jest kilka, którzy tego nie robią. Jeśli twój ORM nie obsługujeasync
, nie próbuj go owijaćTask.Run
ani nic w tym stylu (patrz wyżej).Zauważ, że powiedziałem „ty mógł użyć”. Jeśli mówisz o ASP.NET MVC z pojedynczym zapleczem bazy danych, to (prawie na pewno) nie odniesiesz żadnych korzyści ze skalowalności
async
. Wynika to z faktu, że IIS może obsługiwać znacznie więcej współbieżnych żądań niż jedno wystąpienie serwera SQL (lub innego klasycznego RDBMS). Jednakże, jeśli backend jest bardziej nowoczesny - klaster SQL Server, SQL Azure, NoSQL, etc - a backend można skalować, a skalowalność gardłem jest IIS, a następnie można uzyskać korzyści ze skalowalnościasync
.Tyle, ile chcesz. Należy jednak pamiętać, że wiele ORM ma regułę „jedna operacja na połączenie”. W szczególności EF pozwala tylko na jedną operację na DbContext; dotyczy to zarówno operacji synchronicznej, jak i asynchronicznej.
Pamiętaj również o skalowalności swojego backendu. Jeśli trafiasz w jedną instancję SQL Server, a Twój IIS jest już w stanie utrzymać pełną wydajność SQLServera, to podwojenie lub potrojenie nacisku na SQLServera wcale ci nie pomoże.
źródło
Jak zwykle w programowaniu, to zależy . Zawsze idzie się na kompromis, gdy idzie się określoną ścieżką.
async-await
świeci w miejscach, w których wiesz, że będziesz otrzymywać równoległe żądania do swojej usługi i chcesz mieć możliwość skalowania . Jakasync-await
pomaga skalowanie? W przypadku synchronicznego wywoływania asynchronicznego wywołania we / wy , takiego jak połączenie sieciowe lub trafienie do bazy danych, bieżący wątek odpowiedzialny za wykonanie jest blokowany w oczekiwaniu na zakończenie żądania. Gdy używaszasync-await
, umożliwiasz frameworkowi utworzenie dla ciebie automatu stanów, który zapewnia, że po zakończeniu wywołania We / Wy, twoja metoda kontynuuje wykonywanie od momentu, w którym została przerwana.Należy zauważyć, że ta maszyna stanu ma subtelny narzut. Uczynienie metody asynchroniczną nie przyspiesza jej wykonania , co jest ważnym czynnikiem do zrozumienia i nieporozumieniem wielu osób.
Inną rzeczą, którą należy wziąć pod uwagę podczas korzystania,
async-await
jest fakt, że jest on asynchroniczny do końca , co oznacza, że zobaczysz, że asynchronizacja przenika cały stos wywołań, od góry do dołu. Oznacza to, że jeśli chcesz udostępnić synchroniczne interfejsy API, często zdarza się, że duplikujesz pewną ilość kodu, ponieważ asynchronizacja i synchronizacja nie mieszają się zbyt dobrze.Jeśli zdecydujesz się pójść ścieżką korzystania z asynchronicznych wywołań we / wy, to tak,
async-await
będzie dobrym wyborem, ponieważ coraz więcej nowoczesnych dostawców baz danych ujawnia metodę asynchroniczną implementującą TAP (Task Asynchronous Pattern).Tyle, ile chcesz, pod warunkiem przestrzegania zasad określonych przez dostawcę bazy danych. Nie ma ograniczeń co do liczby połączeń asynchronicznych, które możesz wykonać. Jeśli masz zapytania, które są od siebie niezależne i mogą być wykonywane jednocześnie, możesz obrócić nowe zadanie dla każdego z nich i
await Task.WhenAll
poczekać, aż oba zostaną zakończone.źródło
scale out well
może znaczyćyour server won't die under load
. Lub może to być przypadekonce burned ...
Moje 5 centów:
async/await
tylko wtedy, gdy wykonujesz operację IO, taką jak DB lub usługa zewnętrzna.PS Istnieją wyjątkowe przypadki dla punktu 1, ale w tym celu musisz dobrze zrozumieć wewnętrzne elementy asynchroniczne.
Dodatkową zaletą jest możliwość jednoczesnego wykonywania kilku połączeń We / Wy w razie potrzeby:
źródło
async
akcje pomagają najlepiej, gdy akcje wykonują pewne operacje We / Wy do DB lub niektóre wywołania sieciowe, w których wątek przetwarzający żądanie zostanie zatrzymany, zanim otrzyma odpowiedź z wywołania DB lub wywołania sieciowego, które właśnie wywołałeś. Najlepiej, gdy używasz z nimi opcji oczekiwania i naprawdę poprawi to responsywność twojej aplikacji (ponieważ mniej wątków wejściowych / wyjściowych ASP zostanie zablokowanych podczas oczekiwania na DB lub jakąkolwiek inną operację tego typu). We wszystkich moich aplikacjach, ilekroć wiele połączeń do DB jest bardzo potrzebnych, zawsze zawijałem je w przewidywalną metodę i nazwałem toawait
słowem kluczowym.źródło
Jak wiesz, MVC obsługuje kontrolery asynchroniczne i powinieneś z niego skorzystać. W przypadku, gdy kontroler wykonuje długą operację (może to być dyskowe we / wy lub połączenie sieciowe z inną usługą zdalną), jeśli żądanie jest obsługiwane w sposób synchroniczny, wątek IIS jest cały czas zajęty. W rezultacie wątek czeka tylko na zakończenie długiej operacji. Można go lepiej wykorzystać, obsługując inne żądania, gdy operacja żądana w pierwszej kolejności jest w toku. Pomoże to w obsłudze większej liczby równoczesnych żądań. Twoja usługa będzie wysoce skalowalna i nie będzie łatwo napotkać problem z C10k . Dobrym pomysłem jest użycie async / czekaj na zapytania db. i tak, możesz użyć ich tyle razy, ile uznasz za stosowne.
Spójrz tutaj, aby uzyskać doskonałe porady.
źródło
Z mojego doświadczenia wynika, że dziś wielu programistów używa
async/await
domyślnie kontrolerów.Moją sugestią byłoby, abyś używał go tylko wtedy, gdy wiesz, że ci to pomoże .
Powodem jest to, że, jak już wspomniano Stephen Cleary i inni, może wprowadzać problemy z wydajnością, zamiast je rozwiązywać, i pomoże ci tylko w konkretnym scenariuszu:
źródło
Warto to zrobić wszędzie tam, gdzie można zastosować metodę asynchroniczną, zwłaszcza gdy występują problemy z wydajnością na poziomie procesu roboczego, które zdarzają się w przypadku masowych operacji na danych i obliczeniach. W przeciwnym razie nie ma takiej potrzeby, ponieważ testy jednostkowe będą wymagać odlewania.
Tak, lepiej jest użyć asynchronizacji dla dowolnej operacji DB, aby uniknąć problemów z wydajnością na poziomie procesów roboczych. Zauważ, że EF stworzył wiele alternatyw asynchronicznych dla większości operacji, takich jak:
Niebo jest granicą
źródło