Cannot Access a Disposed Object

Posted on January 28, 2007 at 18:52

In a Windows Forms application that I am working on, I had the following scenario: while the main form (Main.cs) is loading, I prompt the user to prove their credentials. If they are unable to do so, the form is closed (using this.close) and application execution is halted.

The problem is, when I first tried this, I an exception was thrown in Program.cs on the following line:

Application.Run(new Main());

The exception was of type System.ObjectDisposedException, and the accompanying message was “Cannot access a disposed object”.

What happened? According to the official documentation, the method System.Windows.Forms.Application.Run(Form) has the following purpose: “Begins running a standard application message loop on the current thread, and makes the specified form visible.” When this line of code is called, it first instantiates a new instance of the given Windows.Form implementation (in my case, Main.cs) and after it is instantiated, sets the Form.Visible parameter to true, thereby showing the form. In my case, during the instantiation of the form, the Close() method on the form was called, which disposes the Forms object. So when Program.cs attempts to set Main.Visible = true, Main is already disposed and the above error is thrown.

What is the workaround? I can think of two ways off the top of my head (the first one is the one that I ultimately used). Can you think of any others?

  1. Substitute the line in Program.cs with the following. Here the Main class is instantiated first, and only if it is still in existence and not disposed will Application.Run be called. Thus, if Main is closed during instantiation, Application.Run will never be called and the application will close on its own.
Main main = new Main();
if (main != null && !main.IsDisposed) {
  Application.Run(main);
}
  1. Do not call the user authentication code during the instantiation of the main Form of the application. Instead, call it in some event (like Activate) that is tied directly to the creation of the Form, but is not part of the initial instantiation code. In this case the class will instantiate, Application.Run will execute, and only after will the user authentication (and possible subsequent disposal of the form and exit from the application) take place.
  1. 11 Responses to “Cannot Access a Disposed Object”

  2. 1) Red Bug on Mar 19, 2007 | Reply

    Thanks for the code. It solved my problem.

  3. 2) Matej on Jul 28, 2007 | Reply

    Lost an hour on this. Very helpful, thanks a lot.

  4. 3) Jester255 on Aug 13, 2007 | Reply

    Thanks, sorted out my prob.

  5. 4) Nelson on Nov 16, 2007 | Reply

    Thanks a lot! I have been spent 2 hours to try to figure it out.

  6. 5) kiran on Apr 30, 2008 | Reply

    Thanks , it worked well for me

  7. 6) Mjelten on Jun 13, 2008 | Reply

    Perfect! Thanks!

  8. 7) Alexandr on Aug 16, 2008 | Reply

    +5

  9. 8) Anoop Shrivastava on Sep 3, 2008 | Reply

    I Got an error message “Can’t access a disposed object”
    While clicking on button to show the form once viewed.

  10. 9) Loyid Varghese on Oct 7, 2008 | Reply

    Thanks a lot !It solved my problem !

  11. 10) Poolee on Jan 2, 2009 | Reply

    Thanks, also solved my problem. I did consider setting a flag, then checking the flag during .Load… but this seemed messy. Cheers, and Happy New Year. Paul.

  12. 11) Nishantha on Jun 21, 2009 | Reply

    #region Property: Contact
    private Contact current;
    ///
    /// Gets/sets the Contact
    ///
    public Contact Contact
    {
    [System.Diagnostics.DebuggerStepThrough]
    get
    {
    if (this.current == null)
    this.current = new Contact();
    if (this.current != null && this.current.IsDisposed)
    {
    this.current = null;
    this.current = new Contact();
    }
    return this.current;
    }
    }
    #endregion

Post a Comment

Powered by WP Hashcash