Czy zadania są tworzone jako wątki w tle?


85

Zastanawiam się tylko, czy nowa klasa Task w dot.net 4 tworzy wątek tła lub pierwszego planu?

Normalnie ustawiłbym „IsBackground” w wątku, ale nie ma takiego atrybutu w zadaniu.

Nie udało mi się znaleźć żadnej dokumentacji na ten temat w witrynie MSDN :-(

Odpowiedzi:


119

Nie powinno być trudne do zweryfikowania:

class Program
{
    static void Main()
    {
        Task
            .Factory
            .StartNew(() => Console.WriteLine(Thread.CurrentThread.IsBackground))
            .Wait();
    }
}

A odpowiedź brzmi ...

ǝnɹʇ


Mam problem z uruchomieniem wszystkich moich zadań w wątku wywołującym. Wkleiłem tę dokładną linię kodu powyżej do mojego projektu i zgłasza „fałsz”. Czy wiesz, dlaczego tak może być? Używam .NET 4.0.
Trevor Elliott

8
Zgodnie z tym wątkiem stackoverflow.com/questions/7889746/… nie masz gwarancji wątku w tle podczas uruchamiania zadania, ale powinieneś być, jeśli używasz TaskCreationOptions.LongRunning. Używam tej opcji i nadal nie tworzy wątku w tle. Co daje?
Trevor Elliott,

czy można go tak skonfigurować, aby nie?
Royi Namir

2
Uważam, że problem Moozhe'a może dotyczyć domyślnego kontekstu synchronizacji. Zachowanie może się różnić w zależności od tego, czy jesteś w aplikacji WinForms, WPF, Web czy Console, ponieważ wszystkie mają różne domyślne sposoby planowania zadań współbieżnych.
jpierson,

5
kocham twoją odpowiedź: „ǝnɹʇ”. Bardzo zabawny. Dziękuję Ci.
teddy

12

Jeśli zaczynasz Task<T>używać Task.Run(), to tak.

Jeśli używasz asynci await, nie. Wyciąg stąd :

„Słowa kluczowe async i await nie powodują tworzenia dodatkowych wątków. Metody asynchroniczne nie wymagają wielowątkowości, ponieważ metoda asynchroniczna nie działa we własnym wątku. Metoda działa w bieżącym kontekście synchronizacji i wykorzystuje czas w wątku tylko wtedy, gdy metoda jest aktywna. Możesz użyć Task.Run, aby przenieść pracę związaną z procesorem do wątku w tle, ale wątek w tle nie pomaga w procesie, który tylko czeka na udostępnienie wyników ”.


1
Ponieważ używasz Task.Run, będzie to wątek w tle, ale jeśli dojdzie do oczekiwania, może zrobić coś specjalnego, aby wstrzymać wątek i czekać na wyniki. Warto zbadać.
Steztric


0

Zadania są wykonywane przez wątki pochodzące z systemowej puli wątków. Wątek pochodzący z puli wątków jest domyślnie wykonywany w tle.


-1

Jeśli nie jesteś jeszcze przekonany do zadania w tle, po prostu spróbuj uzyskać dostęp do elementu GUI z poziomu zadania, takiego jak:

public async Task<int> ProcessStuff_Async()
{
    while(true)
    {
        label1.Text = "processing next item";

aby uzyskać wyjątek czasu wykonywania:

Niepoprawna operacja między wątkami: kontrolka „label1” uzyskała dostęp z wątku innego niż wątek, w którym została utworzona.

tak jak w przypadku starych dobrych, zwykłych wątków w tle.

W dokumentach MSDN (od 2017 :-) znajdują się informacje, np .:

Najlepszym sposobem, aby sobie z tym poradzić ... jest uruchomienie wątku w tle, który wykonuje pracę za pomocą Task.Run i czekanie na wynik. Dzięki temu interfejs użytkownika będzie działał płynnie podczas wykonywania pracy.

Ten dokument ma nawet sekcję What happens under the covers.


Twoje sprawdzenie potwierdza tylko, że zadanie działa we własnym wątku, a nie, że wątek jest wątkiem w tle. Wątek w tle to wątek, który, jeśli nadal jest wykonywany, nie zapobiegnie zakończeniu programu.
Sören Kuklau
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.