Ich möchte eine Aufgabe auslösen, die in einem Hintergrundthread ausgeführt wird. Ich möchte nicht auf die Fertigstellung der Aufgaben warten.
In .net 3.5 hätte ich Folgendes getan:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
In .net 4 ist die TPL der vorgeschlagene Weg. Das übliche Muster, das ich empfohlen habe, ist:
Task.Factory.StartNew(() => { DoSomething(); });
Die StartNew()
Methode gibt jedoch ein Task
Objekt zurück, das implementiert wird IDisposable
. Dies scheint von Leuten übersehen zu werden, die dieses Muster empfehlen. In der MSDN-Dokumentation zur Task.Dispose()
Methode heißt es:
"Rufen Sie Dispose immer an, bevor Sie Ihren letzten Verweis auf die Aufgabe freigeben."
Sie können dispose für eine Aufgabe erst dann aufrufen, wenn sie abgeschlossen ist. Wenn Sie also den Hauptthread warten und dispose aufrufen, wird der Sinn eines Hintergrundthreads in erster Linie zunichte gemacht. Es scheint auch kein abgeschlossenes / abgeschlossenes Ereignis zu geben, das für die Bereinigung verwendet werden könnte.
Die MSDN-Seite in der Task-Klasse kommentiert dies nicht, und das Buch "Pro C # 2010 ..." empfiehlt dasselbe Muster und kommentiert die Entsorgung von Aufgaben nicht.
Ich weiß, wenn ich es einfach lasse, wird der Finalizer es am Ende fangen, aber wird das zurückkommen und mich beißen, wenn ich viele Feuer mache und Aufgaben wie diese vergesse und der Finalizer-Thread überfordert ist?
Meine Fragen sind also:
- Ist es in diesem Fall akzeptabel,
Dispose()
dieTask
Klasse nicht anzurufen ? Und wenn ja, warum und gibt es Risiken / Konsequenzen? - Gibt es eine Dokumentation, die dies diskutiert?
- Oder gibt es eine geeignete Möglichkeit, das
Task
Objekt, das ich verpasst habe , zu entsorgen ? - Oder gibt es eine andere Möglichkeit, Fire & Forget-Aufgaben mit der TPL auszuführen?