2010-05-06 5 views
37

Wenn ich den folgenden Code-Block in einem Verfahren (unter Verwendung von .NET 4 und der Task Parallel Library) haben:Können .NET-Task-Instanzen während des Laufs den Gültigkeitsbereich verlassen?

var task = new Task(() => DoSomethingLongRunning()); 
task.Start(); 

und die Methode zurückgibt, wird diese Aufgabe außerhalb des Gültigkeitsbereichs gehen und Müll gesammelt werden, oder Wird es bis zum Ende laufen? Ich habe keine Probleme mit GCing bemerkt, aber ich möchte sicherstellen, dass ich mich nicht mit dem GC auf eine Wettlaufsituation einstelle.

+0

Ich fand nach einer Weile eine kleine Sache und ich dachte, ich würde mit Ihnen teilen, der Vollständigkeit halber ... Siehe das Update unten. –

Antwort

30

Update:

Nachdem ich diese Frage beantwortet (! Vor langer Zeit) Ich fand heraus, dass es nicht wahr ist, dass Aufgaben werden immer vollständig ausgeführt - es gibt einen kleinen, sagen wir mal „Ecke“ Fall, Wo Aufgaben nicht abgeschlossen werden können.

Der Grund dafür ist: Wie ich bereits früher geantwortet habe, sind Tasks im Wesentlichen Threads; aber sie sind Hintergrund Threads. Hintergrundthreads werden automatisch beendet, wenn alle Vordergrundthreads beendet sind. Wenn Sie also nichts mit der Aufgabe machen und das Programm endet, besteht die Möglichkeit, dass die Aufgabe nicht abgeschlossen wird.

Sie sollten immer auf Aufgaben warten. Weitere Informationen finden Sie unter excellent answer Jon gave me.


Original:

Aufgabe wird den Threadpool geplant, was bedeutet, dass sie im Wesentlichen threads¹ ist (tatsächlich, sie kapseln Threads).

Vom Thread documentation:

Es ist nicht notwendig, eine Bezugnahme auf ein Thread-Objekt zu erhalten, sobald Sie den Thread gestartet haben. Der Thread wird so lange ausgeführt, bis der Thread abgeschlossen ist.

Also, nein, es besteht keine Notwendigkeit, einen Verweis darauf zu behalten.

Auch stellt die documentation, dass der bevorzugte Weg, um eine Aufgabe zu erstellen, ist es die Fabrik zu verwenden:

Sie auch die StartNew Methode eine Aufgabe in einem Betrieb erstellen und starten können. Dies ist die bevorzugte Art und Weise zu schaffen und Aufgaben zu starten, wenn Erstellung und Terminplanung müssen nicht getrennt (...)

Hoffe, es hilft sein.


¹ entsprechend den documentation:

Eine Aufgabe stellt einen asynchronen Betrieb und in gewisser Weise ist es ähnelt die Schaffung einer neuen Thread oder Threadarbeitseinheit, aber an einem höheres Abstraktionsniveau.

11

Die Aufgabe wird bis zum Abschluss ausgeführt. Auch wenn es keine anderen Verweise darauf gibt (ich bin der Meinung, dass der Begriff nicht verwurzelt ist), wird der Thread-Pool immer noch einen Verweis darauf enthalten und verhindern, dass er zumindest Garbage Collected ist (ich sage zumindest, weil sogar Nach dem Abschluss gibt es keine Garantie, dass es Müll gesammelt wird) bis zur Fertigstellung.

+0

Ja, "verwurzelt" ist der korrekte Ausdruck. Solange * etwas * einen gültigen (Live-) Verweis auf die Aufgabeninstanz hat, ist es nicht für die Sammlung geeignet. In diesem Fall wird der Thread-Pool selbst diese Referenz enthalten, bis der Thread abgeschlossen ist. –

+5

Um genauer zu sein, wird der Taskplaner des TPL einen Verweis auf den Task haben, während er ausgeführt wird. Ohne diese Referenz könnte die Aufgabe Garbage Collected sein, aber das wird den Code nicht stoppen, der vom Finishing ausgeführt wird. – Steven

Verwandte Themen