How To Dispose Members From Forms


When you create a new Form (or UserControl for that matter), Visual Studio creates it as a partial class, with the designer-generated code going into the *.Designer.cs file. One other piece of code that also goes into the designer code is an override of System.ComponentModel.Component.Dispose(bool), which contains the code to dispose the form and its contained components. It always looks like this:


protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

It’s a bit unfortunate that this method is being overridden, because it makes it more difficult to add your own dispose logic to the form, since you can’t override the method once more in the same class – remember that the form code that you control is only part of the class definition. You could obviously edit the designer file directly, but that’s not recommended.


Then what can you do if you need to perform some extra dispose logic in your Form? This need can easily arrive if one of your member variables implement IDisposable, in which case you really should dispose of it when the Form disposes. Imagine you have the following IDisposable class:


public class MyDisposable : IDisposable
{
    private string message_;
 
    public MyDisposable(string message)
    {
        this.message_ = message;
    }
 
    #region IDisposable Members
 
    public void Dispose()
    {
        MessageBox.Show(this.message_);
    }
 
    #endregion
}

You now want to have a MyDisposable member variable in your Form, and you need to dispose of it when the Form disposes:


public partial class MyForm : Form
{
    private MyDisposable myDisposable_;
 
    public MyForm()
    {
        InitializeComponent();
 
        this.myDisposable_ =
            new MyDisposable(“Goodbye, World”);
    }
}

When you run the application and close the Form, the Form is being disposed, but you never see the goodbye message because myDisposable_ is not disposed. The Dispose method in the designer code handles the dispose logic for the form, and it knows nothing about the myDisposable_ member variable.


It does, however, Dispose of its components member, and since this is an IContainer, the problem would be solved if you could add myDisposable_ to the container. Unfortunately, IContainer only accepts IComponent instances, and if you may not want to implement IComponent on MyDisposable.


Part of the contract of IComponent is that an implementation must have a default constructor, and for API design reasons, you may not find that acceptable for your IDisposable type – for some reason, I don’t think that’s an acceptable change for MyDisposable.


What you can do, however, is to add an instance of this little class to the container:


internal class Disposer : Component
{
    private Action<bool> dispose_;
 
    internal Disposer(Action<bool> disposeCallback)
    {
        this.dispose_ = disposeCallback;
    }
 
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
 
        this.dispose_(disposing);
    }
}

From your Form code, you’ll need to wire up a new instance of Disposer with a delegate which will contain the real dispose logic. When used in MyForm, it now looks like this:


public partial class MyForm : Form
{
    private MyDisposable myDisposable_;
 
    public MyForm()
    {
        InitializeComponent();
 
        this.myDisposable_ =
            new MyDisposable(“Goodbye, World”);
        this.components.Add(new Disposer(this.OnDispose));
    }
 
    private void OnDispose(bool disposing)
    {
        this.myDisposable_.Dispose();
    }
}

Notice that I have added a new Disposer instance that points back to the new OnDispose method, which then implements all the dispose logic not handled by the designer code. Now, when I run the application and close the Form, I get the expected MessageBox.


This technique is generally usable whenever you need to dispose of a member variable, but otherwise can’t because the designer code already overrides the Dispose method. However, I only recommend this approach if your member variable doesn’t also implement IComponent.


If the you have control over the member variable’s class and don’t mind having a default constructor, I recommend that you instead implement IComponent (the easiest way to do that is by deriving from System.ComponentModel.Component like I did with the Disposer class). This will generally give you a nicer design-time experience, since you can now just drag the component from the toolbox to the design surface, and the designer (Visual Studio) will automatically add it to the components member variable, and thus it will be disposed together with all the other components in the container.


Both approaches also work if you are creating a UserControl, although there, you’ll probably need to instantiate the components member variable yourself.

Comments (19)

  1. Andreas Ländle says:

    Why not to use the Disposed-Event and dispose your own resources there? That seems to be a much more simple approach to me.

  2. ploeh says:

    Hi Andreas

    Thank you for asking. Indeed, why not?

    There’s a subtle difference in when your event handler gets called. In my example, I’m guaranteed that my event handler (OnDispose) gets called before the Form itself gets disposed. I can be sure of that, since the event handler is invoked on the same thread that disposes the Form itself, and base.Dispose is called after all Components in the container have been disposed.

    If, on the other hand, you attach an event handler to the Disposed event, the event handler is being called much later in the Dispose process. A lot happens before this event is raised, and the Form is virtually destroyed by then.

    Whether it makes a difference for you or not, is not so clear, but it depends on whether you need access to the Form’s members during disposal.

    In the example above, it does make a difference. To test it, I changed my code to this:

    public

    partial class MyForm : Form
    {
       
    private MyDisposable myDisposable_;

        public MyForm()
        {
            InitializeComponent();

            this.myDisposable_ =
               
    new MyDisposable(“Goodbye, World”);

                this.Disposed += new EventHandler(this.OnMyFormDisposed);
        }

        void OnMyFormDisposed(object sender, EventArgs e)
        {
            this.myDisposable_.Dispose();
        }
    }

    What happens then is that although the Dispose method does get invoked on myDisposable_, the MessageBox never appears, since the whole windowing environment has already been destroyed by then.

    Although my approach is more complex, it’s also more robust, since you should always dispose your members before disposing the container; otherwise, unpredictable things may happen.

  3. Keith McCreery says:

    this.components may be null, if the Form has no components defined at design time. This may help…

    if ( this.components == null )

     this.components = new System.ComponentModel.Container();

    this.components.Add(new Disposer(this.OnDispose));

  4. ploeh says:

    Hi Keith

    Thank you for your comment. You are absolutely right – I thought it was a good exercise for the alert reader 😉

  5. Piotr says:

    I have a question. I am programming in C# over two years by now, and i have never needed to execute additional code when Dispose() method of the form is being executed. Can you give an example of what  useful ACTION could i perform in Dispose() ( by placing proper object on components list – like in your example ). And why this cannot be achieved inside the body of Dispose() method?

  6. ploeh says:

    Hi Piotr

    Thank you for asking.

    It’s entirely plausible that you’ve never felt the need to explictly handle Dispose code in your Forms. Many .NET developers don’t put much attention on disposable objects, since the garbage collector will eventually take care of the disposable object. Even if you don’t explicitly dispose of your objects, your code will typically still work, but it will just have a more inefficient memory usage pattern.

    If you mostly use the Forms designer to add components to your Forms, you aren’t going to need the above technique as well, since Components will be added to the Form’s components collection, and thus automatically be disposed when the form disposes.

    A lot of the IDisposable implementations in the BCL also implement IComponent, in which case you can use them directly with the Form’s components collection. An example where the techique described in the post is required then must involve a member variable that implements IDisposable, but not IComponent.

    There are lots of types in the BCL that satisfy this criterion, but an obvious example is System.ServiceModel.ClientBase<TChannel> (a WCF proxy). Imagine that you have a WCF proxy as a member variable. You should dispose of the proxy when the Form disposes, yet the proxy doesn’t implement IComponent.

    As to why this cannot be achieved inside the body of the Dispose method, this is because the Dispose method is already implemented in the designer file (as described in the post). You could edit the designer file, but it’s not recommended.

    HTH

  7. andypaxo says:

    Hi, I realise this is quite a while after your initial post… but I just came across this issue and found your blog.

    You say "You could obviously edit the designer file directly, but that’s not recommended."

    Are you sure about this? The Dispose() method is outside the "Designer generated code" region in the source that VS produces, so it shouldn’t be a problem to edit the method, or move it out of the designer file completely, right?

    Thanks for your help!

  8. ploeh says:

    Hi Andy

    Thank you for your comment. Technically, I think you are correct, but as a rule of thumb, I prefer to leave the designer files alone. AFAIR, there’s no documentation of VS that states that the VS designer only fiddles with the "Designer generated code" region, so you never know…

    Another reason I prefer to not edit the designer file is because it may throw off other team members. Let’s say that you put some logic in the designer file and check it in. Half a year later, some other team member wastes a complete day troubleshooting some weird behavior because he or she doesn’t think about looking in the designer file – it’s not the first place you’ll look for developer-created code 🙂

    So I admit that my motivation for not editing designer files is more ‘soft’ than entirely technical, but I still think they are good reasons.

    HTH

  9. Paul says:

    Hi!

    I’m pretty sure your Disposer component is broken: it really shouldn’t execute the delegate if Dispose is called from the finalizer.

  10. ploeh says:

    Hi Paul

    Thank you for your comment. After having perused your point for a little while, I think I’ll have to disagree.

    There is no finalizer in the Disposer component itself, but it’s conceivable that you may have a finalizer in your parent Form. If this is the case, the Disposer pattern requires you to set the value of the ‘disposing’ parameter to false if you are invoking the virtual Dispose method from your finalizer (for details, see e.g. http://msdn.microsoft.com/en-us/magazine/cc163392.aspx).

    The delegate needs to be unconditionally invoked to ensure that the value of this parameter is always passed – otherwise, the delegate instance will have no way to know whether it is being invoked from Dispose or the Form’s finalizer.

  11. Paul says:

    Hi again

    Firstly, if there is a finalizer in the parent Form or not doesn’t matter, since the designer generated implementation of Dispose(bool) does the correct thing when finalizing: it does *not* call Dispose on the entries in the components collection. It will only ever call the public Dispose() method, namely if disposing==true.

    So if for some reason the Form was not disposed via IDisposable, and therefor gets finalized, the Dispose function in your Disposer class will *not* get called from the Form. Which is a Good Thing ™.

    Now the Disposer class inherits from Component. That also means it inherits the finalizer from Component, which calls Dispose(false), which again is correct. What you should do if disposing==false is release any unmanaged resources that the Disposer class itself uses, but *not* touch any reference types (managed types), because those might already be finalized.

    And not touching any reference types must imply not executing the delegate, since the delegate will always be bound to a reference type (and constitutes a reference type itself if I’m not mistaken). Ok, not always, it could theoretically be bound to a static method, but that’s another can of worms.

    Also there is just no need to ‘forward’ finalization. Finalization means we’re no longer freeing resources deterministically – instead we’re already "too late anyway". Also any objects that we might ‘forward’ the finalization to might already be finalized, or probably will be right away. And if any object we would like to ‘forward’ the finalization to is *not* finalized in the near future, it simply means that it’s still referenced from somewhere, and should not be finalized.

    As I see it calling outside your own class or even touching any reference types (like accessing public fields), is asking for trouble.

    The MSDN article "Implementing a Dispose Method" ( http://msdn.microsoft.com/en-us/library/fs2xkftw(VS.71).aspx ) states this clearly:

    >>>

    If disposing equals false, the method has been called by the runtime from inside the finalizer and only unmanaged resources can be disposed. When an object is executing its finalization code, it should not reference other objects, because finalizers do not execute in any particular order. If an executing finalizer references another object that has already been finalized, the executing finalizer will fail.

    <<<

    So in short: I still believe executing the delegate from Dispose(false) is wrong, and the correct implementation should look like this:

    protected override void Dispose(bool disposing)

    {

       if (disposing)

       {

           this.dispose_(); // no need to pass anything, since it would be always ‘true’

           this.dispose_ = null;

       }

       base.Dispose(disposing); // OK of course, not calling outside the class

    }

    If I’m mistaken please correct me, since I really hope I finally understood at least a good part of the whole "finalization and disposing desaster".

  12. ploeh says:

    Hi Paul

    Thank you for your comment. Everything you are pointing out sounds correct to me, so I think your understanding of the subject is at least as good as mine 🙂

    The reason I think finalizers directly in custom Forms matter is this: Let’s say that you create a custom form that (directly) holds an unmanaged resource. In this case, you should implement a finalizer in the form, so that the unmanaged resource can be freed even in the case where a client forgets to call Dispose.

    This finalizer code needs to be implemented somewhere, but you also want to clean up the unmanaged resource when disposing. Whereever you choose to implement this clean-up code, you need to know whether you are being called from Dispose or the finalizer.

    The callback for the Disposer’s delegate (OnMyFormDisposed in the example above) is an obvious place to put this clean-up code.

    True: When initiated from the Form’s Dispose method, OnMyFormDisposed will always be called with the ‘disposing’ parameter set to false, but you can still call it from the Form’s own finalizer with the value of true.

    There are other solutions to this situation, but when available, I always like to go for one which feels familiar, and in the above way, I follow the normal Dispose pattern.

  13. MAC says:

    I agree with Andy, I think…  Although your method is clever you are adding a layer of complexity that is (in my opinion) unnecessary.  Like Andy I would simply remove the Dispose method from the designer file and place it in the main code file and finally modify this method.

    Just my opinion…

    Good blog and discussion!

  14. ploeh says:

    Hi MAC

    To each his own 🙂

    I completely agree that my method adds another level of indirection (the standard solution to any OO problem), and whether you feel that it’s worth the benefit is impossible to measure.

    I tend to work either by myself, or in tight collaboration with quite experienced developers, so for me, the added complexity comes at a relatively low price.

    If you work in a different development organization, the price may be much higher, to a degree where it makes more sense to directly edit the designer file.

    YMMV 🙂

  15. Lars Eggan says:

    A couple of questions:

    I ported the implementation to VB.NET for testing.

    What I want to achieve is having a place in form classes to dispose of unmanaged code (typical COM-objects) that has the IDisposable interface implemented. (as you)

    1. To instantiate the Disposer class, could this be put in the form Load event? (to have it outside the designer code)

    2. I previously have had a separate method to implement the dispose pattern (i.e. DisposeOfresources) which I call before Form.Dispose(). That is also a safe method or what?

  16. ploeh says:

    Hi Lars

    Thank you for your questions.

    1. In my example, I instantiate the Disposer class in the Form’s constructor, but I don’t see why you couldn’t instantiate it in OnLoad instead. The important step is to instantiate it before or simultaneously with your first unmanaged member. If you wait until after, someone may incorrectly use your Form and dispose of it prematurely, which would cause the Disposer to never get called.

    2. If I understand what you are saying, you are then placing the burden of remembering to call DisposeOfresources on the client of your API. E.g. if someone were to use the C# ‘using’ pattern with your Form, the DisposeOfresources method would not get called, so this doesn’t sound safe.

  17. W says:

    great solution !!!

    though personally i would prefer the disposer to call dispose:

    public class MyDisposable : IDisposable

       {

           private string _message;

           public MyDisposable(string message)

           {

               this._message = message;

           }

           #region IDisposable Members

           public void Dispose()

           {

               MessageBox.Show(this._message);

           }

           #endregion

       }

       internal class Disposer : Component

       {

           private IDisposable _disposable;

           internal Disposer(IDisposable disposable)

           {

               _disposable = disposable;

           }

           protected override void Dispose(bool disposing)

           {

               if (disposing)

               {

                   if (_disposable != null)

                   {

                       _disposable.Dispose();

                   }

               }

               base.Dispose(disposing);

           }

       }

       public partial class Form1 : Form

       {

           private MyDisposable _myDisposable;

           public Form1()

           {

               InitializeComponent();

               _myDisposable = new MyDisposable("Goodbye, World");

               components.Add(new Disposer(_myDisposable));

           }

  18. Ben says:

    I'm coming very VERY late to this party, but one option that no-one seems to have proposed is taking the Dispose method OUT of the Designer file and sticking it in the .cs file. That way other programmers MAY be confused, but they WILL file it…

  19. Kle says:

    Nice one… I would agree that this is up to one's experience and method of writing but I would say that the code is neat and very easy to use so Thanks! for showing us a nice way to dispose.