I want to trigger a task to run on a background thread. I don't want to wait on the tasks completion.
In .net 3.5 I would have done this:
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
In .net 4 the TPL is the suggested way. The common pattern I have seen recommended is:
Task.Factory.StartNew(() => { DoSomething(); });
However, the StartNew()
method returns a Task
object which implements IDisposable
. This
seems to be overlooked by people who recommend this pattern. The MSDN documentation on the Task.Dispose()
method says:
"Always call Dispose before you release your last reference to the Task."
You can't call dispose on a task until it is completed, so having the main thread wait and call dispose would defeat the point of doing on a background thread in the first place. There also doesn't seem to be any completed/finished event that could be used for cleanup.
The MSDN page on the Task class doesn't comment on this, and the book "Pro C#2010..." recommends the same pattern and makes no comment on task disposal.
I know if I just leave it the finalizer will catch it in the end, but is this going to come back and bite me when I'm doing lots of fire & forget tasks like this and the finalizer thread gets overwhelmed?
So my questions are:
- Is it acceptable to not call
Dispose()
on the Task
class in this case? And if so, why and are there risks/consequences?
- Is there any documentation that discusses this?
- Or is there an appropriate way of disposing of the
Task
object that I've missed?
- Or is there another way of doing fire & forget tasks with the TPL?
Question&Answers:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…