Cannot Access a Disposed Object

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) {
  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.
Tagged , , . Bookmark the permalink.

14 Responses to Cannot Access a Disposed Object

  1. Red Bug says:

    Thanks for the code. It solved my problem.

  2. Matej says:

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

  3. Jester255 says:

    Thanks, sorted out my prob.

  4. Nelson says:

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

  5. kiran says:

    Thanks , it worked well for me

  6. Mjelten says:

    Perfect! Thanks!

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

  8. Loyid Varghese says:

    Thanks a lot !It solved my problem !

  9. Poolee says:

    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.

  10. Nishantha says:

    #region Property: Contact
    private Contact current;
    /// Gets/sets the Contact
    public Contact Contact
    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;

  11. Natural Code says:

    thanks buddy

  12. Alain says:

    Thanks for this post. It was just the code snippet I needed!

  13. Vernon says:

    I found that if the form tries to close before it is fully loaded, it causes this error in the program.cs file of a C# program. In this example:

    Application.Run(new Form1());
    catch { }

    the error is ignored and the program will terminate properly. If the program does not need to exit before the form loads, the program will start without issue.

Leave a Reply

Your email address will not be published. Required fields are marked *