2012-03-06 8 views
7

Jest to bardziej ogólne pytanie dotyczące asynchronicznych wzorców w języku C# .NET opisanych na stronie MSDN here.W języku C# .NET, czy operacja asynchroniczna musi utworzyć wątek blokujący?

Gdy długo działa synchroniczny operacja jest wymagana, aby nazwać (np - WCF, DB zapytanie, IO, etc), a ja nie chcę nić, aby zablokować (np - wątek GUI), czy to oznacza że gdzieś musi istnieć inny wątek blokujący?

Czy dokonując synchronicznego połączenia asynchroniczny koniecznie wątku gdzieś zablokować?

Tak więc, jeśli wykonam 10 długich połączeń asynchronicznych (które są w rzeczywistości 10 wywołań synchronicznych), czy musi być 10 wątków, które czekają? A może istnieje mechanizm, który zapobiega blokowaniu 10 wątków?

W WCF można tworzyć metody Begin i End dla wywołania WCF, aby uczynić je asynchronicznymi. Czy to oznacza, że ​​kiedy nazywam tę metodę asynchroniczną, gdzieś jest wątek, na kliencie lub serwerze, który czeka na mnie?

Przeczytałem kilka artykułów na temat różnych metod osiągnięcia asynchronii, ale te artykuły nie wyjaśniają, co dzieje się pod maską.

Aktualizacja

zrobiłem moje pytanie bardziej SZCZEGÓLNE, ponieważ jestem bardziej zainteresowany o .NET. wzorce asynchroniczne opisane przez MSDN.

Aktualizacja 2

I zreformował pytanie jeszcze bardziej specyficzne co synchronicznego połączeń asynchronicznych.

Odpowiedz

7

W ramach .NET istnieje wiele sposobów wdrożenia operacji asynchronicznej: za pomocą wątku, puli wątków, metod BeginXxx i EndXxx, opartego na zdarzeniach APM lub zadania opartego na zadaniu.

Każdy wzór asynchroniczny posiada własną realizację wewnętrznego i wszystkie te modele Programowanie asynchroniczne są wyjaśnione na tym blogu article, w tym tradycyjnym BeginXxx i EndXxx asynchronicznym wzorca.

Poniżej znajduje się zestawienie wszystkich wzorców ASYNC dla podręczne: Async Summary:

Ponadto Jeffrey Richter wyjaśnia również CLR Asynchronous Programming Model w MSDN Magazine ładnie.

+0

Wielką link do artykułu. Więc nie mówi tego wprost, ale wygląda na asynchroniczne wywołania niskiego poziomu, odbywa się to bez blokowania wątków. Ale jeśli chcesz wykonać synchroniczne wywołanie asynchroniczne, musisz utworzyć wątek. Czy mam rację? – Mas

+0

@Mas Tworzenie "wątku" jest tylko jednym ze sposobów na jego asynchronizację. Jak wyjaśniono w Podsumowaniu w odpowiedzi, istnieją inne sposoby konwertowania połączeń synchronizacyjnych na połączenia asynchroniczne. – VS1

+0

Zgodnie z tabelą wszystkie wzorce Asynchroniczne są oparte na wątkach (Zadania używają wątków w tle). – Mas

2

Niestety, nie ma jednej odpowiedzi na to pytanie. Niektóre biblioteki zapewniają natywnie implementowane operacje asynchroniczne, takie jak na przykład gniazda, w których jest obsługiwany przez sprzęt. Inni mogą nie, jak w przypadku biblioteki strony trzeciej, która może bardzo dobrze blokować.

3

Nie musi to być jeden wątek na operację. Jak mówi @Ioannis Karadimas, najprawdopodobniej zależy to od implementacji.

Na przykład wyobraź sobie, że chcę, aby asynchroniczny odbierał z 10 różnych gniazd. Można to osiągnąć za pomocą jednego dodatkowego wątku za pomocą wywołania do wybrania w pętli, która nie deterministycznie wybiera jedno dostępne gniazdo po odebraniu wiadomości.

2

"Tak więc, jeśli wykonam 10 długich połączeń asynchronicznych, czy musi być 10 nici, które czekają?" Ogólnie rzecz biorąc, nie.

"Czy istnieje mechanizm zapobiegający blokowaniu 10 wątków?" - istnieją mechanizmy pozwalające 1 wątkowi blokującemu na przetwarzanie wielu elementów. Prosty przykład - wątek jądra może czekać na sygnał NIC i semafor kolejki wejściowej - zwykle jest zablokowany, czekając na jeden lub drugi. Twoja asynchroniczna aplikacja użytkownika umieszcza w kolejce wysyłkę sieciową, a wątek jądra pobiera ją z kolejki i próbuje przesłać do karty sieciowej. Jeśli nie, dodaje ją do wewnętrznej kolejki wysyłania i wraca do aplikacji z odpowiedzią "WOULD_BLOCK". Gdy sprzęt jest gotowy, sygnalizuje wątek jądra, który usuwa kolejkę bufora wysyłania i ładuje go na sprzęt.Podobnie Twoja aplikacja wysyła jedną lub więcej żądań asynchronicznych recv() (z buforami), a wątek jądra dodaje ją do listy i zwraca z odpowiedzią "WOULD_BLOCK". Gdy dane docierają do karty NIC, jego sterownik sygnały i wątek jądra sprawdza dane i próbuje znaleźć wpis na swojej liście, która czeka na te dane. Jeśli są to dane dla aplikacji, kopiuje ona/DMA dane ze sprzętu do buforów i wywołuje asynchroniczne wywołanie zwrotne (zauważ, jak dokładnie wywoływane jest wywołanie zwrotne asycn, i w jakim wątku jest zależny od systemu operacyjnego.) Maybee a APC jest umieszczany w kolejce do wątku GUI lub struktura zakończenia IOCP jest umieszczana w kolejce do puli wątków użytkownika).

W każdym razie wątek jądra może zawierać wiele wpisów z wielu procesów na swojej wewnętrznej liście wysyłkowej lub liście artykułów. Ilekroć sprzęt lub jego kolejka wejściowa wymagają uwagi, uruchamia się i obsługuje, w przeciwnym razie pozostaje zablokowana.

1

Nie będzie żadnego wątku OCZEKUJĄCEGO, jeśli wykonasz wywołanie Async przy użyciu bibliotek Framework. na przykład Jak w twoim przypadku użycia wspomniałeś "W WCF, możesz utworzyć metody Begin i End dla wywołania WCF, aby uczynić je asynchronicznymi. Czy to oznacza, że ​​gdy wywołuję tę metodę asynchroniczną, jest gdzieś wątek, albo na kliencie lub serwer, który czeka na mnie? "

Tam przyzwyczajenie być dowolny wątek czekając na działania Async zostać zakończone, więcej szczegółów można sprawdzić ten doskonały blogowi http://blog.stephencleary.com/2013/11/there-is-no-thread.html

Powiązane problemy