Czy Task.Delay jest naprawdę asynchroniczny, tak jak operacja we / wy, tj. Czy opiera się na sprzęcie i przerwaniach zamiast na wątku?
Znalazłem mnóstwo powiązanych treści, które owijały się w bawełnę i nigdy nie byłem w stanie znaleźć odpowiedzi. Jestem prawie w 100% pewien, że Task.Delay(int)
nie używa wątku, ponieważ mogę uruchomić ten kod na moim komputerze z zaledwie 16 procesorami logicznymi:
var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);
I zajmuje to dziesięć sekund. Wydaje mi się, że gdyby używał około stu tysięcy wątków, zajęłoby to trochę więcej czasu.
Więc moje pytanie brzmi: jak to Task.Delay(int)
działa? Nie w sposób, na jaki wskazuje to słabo zatytułowane pytanie SO , ale z punktu widzenia wątków i zasobów sprzętowych.
Odpowiedzi
W obecnej implementacji platformy .NET istnieje pojedynczy „wątek czasomierza”, który po prostu śledzi wystąpienia zarządzanych czasomierzy i zgłasza ich zdarzenia w odpowiednich momentach. Ten wątek czasowy będzie blokował swój sygnał sterujący z limitem czasu ustawionym na należny czas dla następnego timera. Sygnał sterujący jest używany do dodawania / usuwania / zmiany timerów, więc kiedy to żądanie blokowania wygaśnie, wątek timera wie, że następny timer został uruchomiony. Jest to normalna operacja blokowania wątków, więc wewnętrznie wątek jest w stanie bezczynności i jest usuwany z kolejki programu planującego do czasu zakończenia tej operacji blokowania lub przekroczenia limitu czasu. Limit czasu tych operacji jest obsługiwany przez przerwanie timera harmonogramu systemu operacyjnego.
Więc technicznie istnieje wątek, ale jest to tylko jeden wątek na proces, a nie jeden wątek na Task.Delay
.
Ponownie podkreślam, że dzieje się tak w obecnej implementacji .NET. Zaproponowano inne rozwiązania, takie jak jeden wątek czasomierza na procesor lub dynamiczna pula wątków czasomierza. Być może eksperymentowano z nimi iz jakiegoś powodu odrzucono, a może w przyszłości zostanie przyjęte alternatywne rozwiązanie. AFAIK nie jest to nigdzie oficjalnie udokumentowane, więc jest to szczegół implementacji.