Is it considered acceptable to not call Dispose() on a TPL Task object?

.net, c#, dispose, multithreading, task-parallel-library

Solution

There is a discussion about this in the MSDN forums.

Stephen Toub, a member of the Microsoft pfx team has this to say:

Task.Dispose exists due to Task potentially wrapping an event handle used when waiting on the task to complete, in the event the waiting thread actually has to block (as opposed to spinning or potentially executing the task it's waiting on). If all you're doing is using continuations, that event handle will never be allocated ... it's likely better to rely on finalization to take care of things.

Update (Oct 2012) Stephen Toub has posted a blog titled Do I need to dispose of Tasks? which gives some more detail, and explains the improvements in .Net 4.5.

In summary: You don't need to dispose of `Task` objects 99% of the time.

There are two main reasons to dispose an object: to free up unmanaged resources in a timely, deterministic way, and to avoid the cost of running the object's finalizer. Neither of these apply to `Task` most of the time:

- As of .Net 4.5, the only time a `Task` allocates the internal wait handle (the only unmanaged resource in the `Task` object) is when you explicitly use the `IAsyncResult.AsyncWaitHandle` of the `Task`, and

- The `Task` object itself doesn't have a finalizer; the handle is itself wrapped in an object with a finalizer, so unless it's allocated, there's no finalizer to run.

Problem

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?

Original source

Related problems