5 Replies - 12256 Views - Last Post: 10 December 2012 - 04:39 AM

#1 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 767
  • Joined: 19-October 11

Disposing objects - Everything about Dispose()

Posted 21 November 2012 - 10:20 AM

We've all seen this question arising from time to time, and we have partial answers all over the place. So, how to be close to 100% sure, which objects need to be disposed? I'd like this debate to be a good reference topic for anyone in doubt about how and when to dispose objects.

I'll start with what I know.

One should dispose objects that:
  • implement IDisposable interface
  • have Dispose() method (meaning they don't implement IDisposable directly, but are derived classes from class, who has implemented IDisposable interface)


Additionally one should implement IDisposable interface to ones one classes, when they are accessing external (unmanaged) resources. And of course dispose them after they've been used.

How to know which objects implement IDisposable interface?

Search for MSDN ClassName in google.com or similar, and take a look under the Syntax section (second big blue text from the top usually). For example SpeechSynthesizer
'Declaration
Public NotInheritable Class SpeechSynthesizer _
	Implements IDisposable



How to know which objects implement Dispose() method?

Same as above: take a look at MSDN or use F2 (object browser) in Visual Studio, and search there for what your interest is.

How to dispose objects?

If you can, do it with Using block:
        'needs reference to System.Speech (right click on project, and add reference)
        Using mySpeechObject As New System.Speech.Synthesis.SpeechSynthesizer
            mySpeechObject.Speak("Something to speek!")
        End Using

        'another example
        Using myReader As New IO.StreamReader("C:\test.txt")
            Dim textFromFile = myReader.ReadToEnd()
        End Using


Why "if you can"? In example code above, how would you use SpeakAsync method for mySpeechObject?

So how to do it, if you can't do it in Using block? By calling Dispose() method on the object. Let's continue with SpeechSynthesis class example:

    Sub Main()
        Dim mySpeechObject As New System.Speech.Synthesis.SpeechSynthesizer
        mySpeechObject.SpeakAsync("Something to speek!")
        AddHandler mySpeechObject.SpeakCompleted, AddressOf SpeachEnded
    End Sub

    Private Sub SpeachEnded(sender As Object, e As Speech.Synthesis.SpeakCompletedEventArgs)
        TryCast(sender, SpeechSynthesizer).Dispose() 'if you're having Option Strict On
        'sender.Dispose() 'if you're having Option Strict Off
    End Sub



When you don't need to dispose object, even if it implements IDisposable, or inherits Dispose()?
*Warning*: example below is just example, and doesn't represent good programming practice. Example class EncapsulatedObject should implement IDisposable, and be disposed when out of use!

When object, that should be disposed, is encapsulated by managed code, that consequentially disposes it with itself:

'form example:
Option Strict On
Imports System.Speech.Synthesis

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim myInstanceOfEncapsulatedObject As New EncapsulatedObject
        Using myReader As New IO.StreamReader("C:\test.txt")  'put in test.txt really long text
            myInstanceOfEncapsulatedObject.SpeekText(myReader.ReadToEnd())
        End Using

    End Sub
End Class

Class EncapsulatedObject
    Private mySpeechObject As New System.Speech.Synthesis.SpeechSynthesizer

    Public Sub SpeekText(text As String)
        mySpeechObject.SpeakAsync(text)
    End Sub
End Class



Why EncapsulatedObject in previous example should implement IDisposable? Try the following example (edit:and close the app, while it's still speaking):

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim myInstanceOfEncapsulatedObject As New EncapsulatedObject
        myInstanceOfEncapsulatedObject.SpeekText("Really long text example: All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher. No patent liability is assumed with respect to the use of the information contained herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions. Nor is any liability assumed for damages resulting from the use of the information contained herein.")
    End Sub
End Class

Class EncapsulatedObject
    Private mySpeechObject As New System.Speech.Synthesis.SpeechSynthesizer

    Public Sub SpeekText(text As String)
        mySpeechObject.SpeakAsync(text)
    End Sub
End Class



A rule of thumb for disposing objects
Each time you know you are dealing with outer resources (files, databases,...) dispose such objects. Better be safe than sorry ;)/>/>

Note: I'm aware there could be wrong information in what I just posted, and that's why I opened this topic. I'd like to have a debate on disposing objects, so everyone who is not sure about it, could benefit.

This post has been edited by lucky3: 27 November 2012 - 10:55 AM


Is This A Good Question/Topic? 3
  • +

Replies To: Disposing objects - Everything about Dispose()

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 992
  • View blog
  • Posts: 972
  • Joined: 30-September 10

Re: Disposing objects - Everything about Dispose()

Posted 21 November 2012 - 02:53 PM

I think this post is a good idea :)/>

My opinion on this topic is that if a type implements IDisposable, you should strive to call Dispose() on it. Out of general good practice for one thing, and to make sure the software behaves itself (doesn't hog a file that it has long since finished with, for example), but also to easily avoid the performance costs of finalization. Objects will be collected earlier by the garbage collector if they don't have to be finalized (if a finalizer has been defined, obviously).

The exception to that rule for me is when it is prohibitively awkward to call Dispose(), as the lifetime of the object is difficult to track. Note, this is very rarely the case, so it shouldn't be used as an excuse to be lazy!

When this is the case, I may leave the garbage collector to finalize the object for me (which will in turn call Dispose() for me to clean up any unmanaged resource held by the disposable type), assuming the type defines a finalizer. This will incur a small performance hit, that will usually not be worth worrying about. Note though that this is definitely not a general habit anyone should be getting into.

The single example of this exception that I personally have come across is the System.Threading.Task.Task class (and its generic equivalent; Task<TResult>). These two classes implement IDisposable, but I often don't call Dispose() on instances of these classes.

The reason is, I use them to perform asynchronous operations, and so it's often very difficult to know for sure when calling code has completely finished with tasks, and I may have to hook up ugly continuations that clutter the code, and make it more complex.

Therefore, I choose to keep the code clean and simple, and I let the garbage collector clear things up for me if it gets a chance, and take the small performance hit that that entails. Plus, I happen to know that Task.Dispose() only does anything meaningful under certain circumstances, of which cause a wait handle to be allocated that requires disposal.

For more info on Tasks (in the context of Dispose()), and some general insight on calling Dispose() from a Microsoft PFX Team member, see here.


Also, here is a collection of topics from the C# forum that relate directly to this topic, which may be useful:

Disposal Paranoia Part 1

Disposal Paranoia Part 2 (Involving Tasks)

When are WinForms, and WinForm components disposed, and where events fit in to garbage collection

This post has been edited by CodingSup3rnatur@l-360: 31 January 2013 - 12:21 PM

Was This Post Helpful? 1
  • +
  • -

#3 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2270
  • View blog
  • Posts: 9,496
  • Joined: 29-May 08

Re: Disposing objects - Everything about Dispose()

Posted 21 November 2012 - 03:07 PM

IDisposable is often (and should be) Implemented by object that have handles to OS / hardware. On disposal the object can relinquish the handles it has control off.
Was This Post Helpful? 1
  • +
  • -

#4 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1062
  • View blog
  • Posts: 4,140
  • Joined: 02-July 08

Re: Disposing objects - Everything about Dispose()

Posted 22 November 2012 - 12:37 PM

Always dispose of any and all graphics objects i.e. fonts, pens, brushes, graphicspaths, created graphic objects, bitmaps etc... They all implement IDisposable, so it should be utilized for best practice.

Using cg As Graphics = Me.CreateGraphics
...
End Using

This post has been edited by _HAWK_: 22 November 2012 - 12:38 PM

Was This Post Helpful? 1
  • +
  • -

#5 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 992
  • View blog
  • Posts: 972
  • Joined: 30-September 10

Re: Disposing objects - Everything about Dispose()

Posted 07 December 2012 - 07:51 AM

Uses of finalizers, and problems with using them
Was This Post Helpful? 1
  • +
  • -

#6 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 992
  • View blog
  • Posts: 972
  • Joined: 30-September 10

Re: Disposing objects - Everything about Dispose()

Posted 10 December 2012 - 04:39 AM

In the topic linked below, myself and Skydiver explain client event subscriptions and there role in memory leaks (which has nothing to do with calling Dispose(), but the two issues are often wrongly thought as being related for some reason), and the way IDisposable is generally unrelated to the garbage collector and the reclaiming of memory.

In summary, IDisposable is generally about freeing resources that the garbage collector cannot (like file handles). The garbage collector is simply about reclaiming the raw memory that your objects occupy, and doesn't have any knowledge of external resources like file handles, database connections etc, which is why we need IDisposable to release such resources.

See here for the topic.

This post has been edited by CodingSup3rnatur@l-360: 10 December 2012 - 07:03 AM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1