Don't bother disposing of your tasks, not unless performance or scalability testing reveals that you need to dispose of them based on your usage patterns in order to meet your performance goals.
Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
// If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. private void Dispose(bool disposing) { // Check to see if Dispose has already been called.
The Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.
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:
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
, andTask
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.This is the same kind of issue as with the Thread class. It consumes 5 operating system handles but does not implement IDisposable. Good decision of the original designers, there are of course few reasonable ways to call the Dispose() method. You'd have to call Join() first.
The Task class adds one handle to this, an internal manual reset event. Which is the cheapest operating system resource there is. Of course, its Dispose() method can only release that one event handle, not the 5 handles that Thread consumes. Yeah, don't bother.
Do beware that you ought to be interested in the task's IsFaulted property. It's a fairly ugly topic, you can read more about it in this MSDN Library article. Once you deal with this properly, you should also have a good spot in your code to dispose the tasks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With