Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 42759|Odpowiedź: 5

[Źródło] Dlaczego .net/c# Task jest wolniejszy niż Thread?

[Skopiuj link]
Opublikowano 03.05.2017 16:40:28 | | | |
.NET 4 zawiera nową przestrzeń nazw, System.Threading.Tasks, która zawiera klasy abstrahujące funkcjonalność wątków. Używaj ThreadPool w tle. Zadanie reprezentuje pracę jednostki, którą należy wykonać. Praca tej jednostki może być wykonywana w osobnym wątku lub zadanie może być uruchamiane synchronicznie, co wymaga oczekiwania na główny wątek strojenia. Korzystanie z zadań nie tylko daje warstwę abstrakcji, ale także dużą kontrolę nad wątkami leżącymi u podstaw.
Zadania dają dużą elastyczność w planowaniu pracy, którą trzeba wykonać. Na przykład możesz zdefiniować zadanie ciągłe – co należy wykonać po jego zakończeniu. To może decydować o sukcesie lub niepowodzeniu. Ponadto zadania mogą być ułożone w hierarchię. Na przykład zadanie nadrzędne może utworzyć nowe zadanie potomne. Tworzy to zależność, dzięki której jeśli anulujesz zadanie nadrzędne, jego zadanie podrzędne również zostanie anulowane.


Obecnie popularne jest stosowanie metod wykonywania zadań, które są wysokowydajne, a nie wiem, gdzie jest wydajność zadań.

Sam testowałem Task i Thread i uważam, że Task jest bardzo wolny, co znacząco wpływa na wydajność, a kod testowy wygląda następująco:

Przechodzimy przez tę metodę 1000 razy, a następnie metoda blokuje się przez 100 milisekund, a wynik testu jest następujący:



Wynik:
Wykonanie nici trwa 188 milisekund
Wykonanie zadania trwa 14 671 milisekund


Różnica prędkości między nimi wynosi 78 razy!!

Zadanie jest bardzo wolne, nie wiem, dlaczego tak się dzieje, czy coś jest nie tak z moim kodem testowym, czy co? Mam nadzieję, że wyjaśnisz, dlaczego tak się dzieje...




Poprzedni:Wysyłaj wiadomości za pomocą ASP.NET Core
Następny:C# Obliczenia równoległe Parallel.For&Parallel.For
 Ziemianin| Opublikowano 13.10.2020 10:47:17 |
tongli1996218 Opublikowano 2020-10-13 09:34
Aby zapewnić ten sam kod co w Thread, moja operacja to następujący kod, a powyższy to pseudo-kod
PS: Po prostu dzwoń i czekaj na zadanie. Opóźnij bez dodawania...

Tak, dzięki

Czas wykonania zadania: 117.0357

Kod można modyfikować w następujący sposób:

Task.Run zastępuje Task.Factory.StartNow, ponieważ automatycznie rozpakowuje zadania wewnętrzne.
Task.WaitAll czeka na zadanie zewnętrzne zamiast wewnętrznego. Korzystanie z Task.Run nie ma zagnieżdżonych zadań.


Patrząc na dokumentację msdn, widać, że metoda Task.Delay Method tworzy zadanie, które kończy się po określonej liczbie milisekund. (W rzeczywistości zostanie utworzony nowy wątek i dodana zostanie opcja oczekiwania, która czeka na wykonanie zadania, nie wiem, czy dobrze rozumiem)

Logowanie do linku jest widoczne.

Dodatkowo istnieje różnica między zadaniem a nieważnością

Zadanie zwraca asynchroniczną metodę, która może czekać
Metoda void return asynchroniczna nie może czekać, działa asynchronicznie, nie możesz wiedzieć, kiedy jest skończona, nie możesz monitorować statusu tej operacji asynchronicznej.


Odniesienie:

Logowanie do linku jest widoczne.
Logowanie do linku jest widoczne.

Podsumowując: jest problem z kodem, nie powinienem używać Thread.Sleep w metodzie Task
Opublikowano 21.07.2020 13:09:29 |
Miałem dziś ten sam problem, używając wielowątkowania do szyfrowania AES, Task jest dużo wolniejszy niż Thread!!
Czy właściciel znalazł powód?
Opublikowano 12.10.2020 19:24:48 |
Ten post został ostatnio edytowany przez tongli1996218 w dniu 12.10.2020 o 19:43

Po przetestowaniu kodu właściciela, gdy program jest uruchamiany i uruchamiany wielokrotnie, czas działania zadania będzie się skracać, a na moim komputerze jest skrócony do mniej niż Thread, a Thread jest stabilny w tym czasie.

Później odkryto, że metoda Thread.Sleep(100) miała negatywny wpływ na Task, ale nie na Thread, i Thread.Sleep(100) można było zastąpić innymi czasochłonnymi weryfikacjami programu, takimi jak numeryczne samododawanie lub await Task.Delay(100).

PS: Thread.Sleep zakończy aktualny czas cięcia wątków po wywołaniu, na przykład Thread.Sleep(0) zakończy aktualny czas cięcia wątku i przeniesie go do innych wątków do uruchomienia. Wewnątrz zadania znajduje się pula wątków, która może optymalizować przełączanie kontekstu wątków i skrócić czas utraty CPU (szczególnie przy optymalizacji procesora wielordzeniowego), podczas gdy Thread.Sleep(100) zakłóca logikę przełączania oryginalnej puli wątków zadania, powodując znaczne straty czasu CPU

Jeśli zastąpisz Thread.Sleep(100) na await Task.Delay(100), okaże się, że czas trwania zadania przekracza 100 milisekund, jak pokazano poniżej:
private void TaskTest()
{
        Thread.Sleep(100);
         ... Wykonaj tę czynność
}
Zastąpione przez
private async void TaskTest()
{
      oczekuj na zadanie. Opóźnienie (100);
      ... Wykonanie zadania trwa ponad 100 milisekund, co jest takie samo jak oryginalny Thread.Sleep(100) dla Thread
}




 Ziemianin| Opublikowano 12.10.2020 22:53:05 |
tongli1996218 Opublikowano 2020-10-12 19:24
Po przetestowaniu kodu właściciela, gdy program zostanie uruchomiony, czas działania zadania będzie się dalej zmniejszać po wielokrotnym uruchomieniu, a na moim komputerze zostanie skrócony do mniej niż Thread...

Próbowałem zmienić to na kod w ten sposób:
Zadanie.Opóźnienie(100000);

Czas wykonania zadania:14.1306 ms, całkowity czas jest rzeczywiście bardzo krótki, jednak zauważyłem, że metoda wywołana przez Zadanie nie zakończyła wykonania.
Opublikowano 13.10.2020 09:34:33 |
Ten post został ostatnio edytowany przez tongli1996218 w dniu 13.10.2020 09:40
Opublikowano 2020-10-12 22:53
Próbowałem zmienić to na kod w ten sposób:
Zadanie.Opóźnienie (100000);

Aby zapewnić ten sam kod co w Thread, moja operacja to następujący kod, a powyższy to pseudo-kod
PS: Po prostu wywołaj await Task.Delay, a następnie nie dodawaj kodu, wątek otwarty przez zadanie jest zwracany natychmiast, aby zapewnić symulację ograniczoną od obliczeń, możesz użyć (int a = 0; a< 1000000; ++a){}; Takie metody zamiast tego

private async static void TaskTest()
        {
            czekaj na zadanie.Opóźnienie(100000);
             Zablokowane. Przyrost (bieg ref);    blokada, ale góra jest mniejsza
            if(run == j)
             {
                Stoper. Stop(); Zatrzymaj monitoring
                TimeSpan czasowy = stoper. Upływ;  Otrzymuje łączny czas mierzony przez bieżącą instancję
                Console.WriteLine("Czas wykonania zadania:" + czas. Całkowite Milisekundy); Całkowita liczba milisekund
              }
        Czas potrzebny jest również bardzo krótki


Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com