Chcę uruchomić zadanie w wątku w tle. Nie chcę czekać na zakończenie zadań.
W .net 3.5 zrobiłbym to:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
W .net 4 TPL jest sugerowanym sposobem. Typowy zalecany wzór, który widziałem, to:
Task.Factory.StartNew(() => { DoSomething(); });
Jednak StartNew()
metoda zwraca Task
obiekt, który implementuje IDisposable
. Wydaje się, że jest to przeoczane przez osoby, które zalecają ten wzór. Dokumentacja MSDN dotycząca Task.Dispose()
metody mówi:
„Zawsze wywołuj Dispose, zanim zwolnisz ostatnie odniesienie do zadania”.
Nie możesz wywołać dispose na zadaniu, dopóki nie zostanie ono zakończone, więc pozostawienie głównego wątku oczekiwania i wywołania dispose pokonałoby w pierwszej kolejności punkt robienia w wątku w tle. Wydaje się również, że nie ma żadnego zakończonego / zakończonego wydarzenia, które można by wykorzystać do czyszczenia.
Strona MSDN w klasie Task nie komentuje tego, a książka „Pro C # 2010 ...” zaleca ten sam wzorzec i nie komentuje usuwania zadań.
Wiem, że jeśli po prostu zostawię to, finalizator w końcu to złapie, ale czy to wróci i mnie ugryzie, gdy będę wykonywać wiele zadań typu „odpal i zapomnij”, a wątek finalizatora zostanie przeciążony?
Więc moje pytania to:
- Czy dopuszczalne jest, aby nie dzwonić
Dispose()
naTask
klasy w tym przypadku? A jeśli tak, dlaczego i czy istnieje ryzyko / konsekwencje? - Czy jest jakaś dokumentacja, która to omawia?
- A może istnieje odpowiedni sposób na pozbycie się
Task
przedmiotu, który przegapiłem? - A może istnieje inny sposób wykonywania zadań „odpal i zapomnij” z TPL?