C# Form.Close VS Form.Dispose

C# Form.Close vs Form.Dispose

This forum on MSDN tells you.

Form.Close() sends the proper Windows
messages to shut down the win32
window. During that process, if the
form was not shown modally, Dispose is
called on the form. Disposing the form
frees up the unmanaged resources that
the form is holding onto.

If you do a form1.Show() or
Application.Run(new Form1()), Dispose
will be called when Close() is called.

However, if you do form1.ShowDialog()
to show the form modally, the form
will not be disposed, and you'll need
to call form1.Dispose() yourself. I
believe this is the only time you
should worry about disposing the form
yourself.

Proper way to dispose a new Form

Hmm, "code cracker" appears to be a very appropriate term for that tool, its advice certainly made you write code that breaks your program. Golden Rule is to never trust IDisposable advice from a static code analysis tool, none of them ever have sufficient insight in code execution. They can never figure out which Dispose() call gets the job done.

What it cannot see is that the Form class already knows how to dispose itself. It is very easy for it to do so, the object becomes unusable when the window closes. When there is no more window then there's no reason to keep using the Form object. A luxury that isn't otherwise very common in .NET but certainly inspired by very smart programmers that worked for Xerox 45 years ago.

There is only one special rule you have to keep in mind, it does not dispose itself when you use ShowDialog() to display the window. That was intentional, it makes retrieving the dialog results too risky. Using the using statement for a ShowDialog() call is very easy to do, the call does not return until the window is closed.

Does a Windows.Form need to be disposed after being closed?

The general rule is anything which implements IDisposable should be disposed. This includes forms, since the base Form is IDisposable. Furthermore, steps should be taken to ensure disposal even in the event of an exception. Therefore, the better pattern typically looks like this:

if (sth_goes_wrong) {
using (var formWarn = new FormWarn("explanatory message..."));
{
formWarn.ShowDialog();
}
}

Note I did not use the member variable and showed the form using a blocking dialog.

Alternatively, you can continue using the member variable. However, in that case you need to override the current form's Dispose() method to also dispose your formWarn instance, if it exists, and the code in question should look like this:

if (sth_goes_wrong) {
this.formWarn = this.formWarn ?? new FormWarn();
formWarn.Message = "explanatory message...";
formWarn.Show();
}

where you also added that new Message property allowing you to update an existing instance.

Using dispose() method instead of close() method to a form

The basic difference between Close() and Dispose() is, when a Close() method is called, any managed resource can be temporarily closed and can be opened once again. It means that, with the same object the resource can be reopened or used. Where as Dispose() method permanently removes any resource ((un)managed) from memory for cleanup and the resource no longer exists for any further processing.


Or just a general statement. With the connection object calling Close() will release the connection back into the pool. Calling Dispose() will call Close() and then set the connection string to null.

Some objects such as a Stream implement IDisposable but the Dispose method is only available if you cast the object to an IDisposable first. It does expose a Close() method though.

I would always argue that you should call Dispose() on any object that implements IDisposable when you are through with the object. Even if it does nothing. The jit compiler will optimize it out of the final code anyway. If the object contains a Close() but no Dispose() then call Close().

You can also use the using statement on IDispoable objects

using(SqlConnection con = new SqlConnection())
{
//code...
}

This will call Dispose() on the SqlConnection when the block is exited.

How do I prevent a form object from disposing on close?

By default, when you close a form, it will be disposed. You have to override the Closing event to prevent it, for example:

// Use this event handler for the FormClosing event.
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
e.Cancel = true; // this cancels the close event.
}

Dispose form after closing

This question turns out to be about Dispose.

Firstly, Dispose has nothing to do with garbage collection. The following happens:

  1. You have a global Timer instance
  2. You create form2
  3. Form2 subscribes to the timer
  4. Form2 is Closed and/or Disposed
  5. The Timer event fires, increments the counter and shows a MessageBox
  6. The Timer event keeps firing until the App closes.

The main point to understand is that Close/Dispose only change the status of the Form, they don't (can't) 'delete' the instance. So the (closed) form is there, the counter field is still there and the Event fires.


OK, part 1:

A using () {} block would be better but this should work:

    private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
/// I've tried Dispose() method . but didn't work
form.Dispose(); // should work
}

If not, please describe "doesn't work".



    private void Form2_Load(object sender, EventArgs e)
{
Program.timer.Tick += timer_Tick;
Close();
/// I've tried Dispose() method instead of Close() . but didn't work
}

This is strange, but I'll assume that it is artifical code for the question.

Your global Program.Timer now stores a reference to your Form2 instance and will keep it from being collected. It does not prevent it from being Disposed/Close so your timer will keep firing for a Closed Form, and that will usually fail and cause other problems.

  1. Don't do this (give Form2 it's own timer)
  2. Use a FormClosed event to unsubscribe: Program.timer.Tick -= timer_Tick;

Difference form.Close() and form.hide()

Hide makes the form invisible to the user. Close actually closes it and calls dispose on it.

From: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx

"When a form is closed, all resources created within the object are closed and the form is disposed. "

WinForms Dialog Form -- Close or Dispose?

I would use a using statement:

  using (var frm = new ChangePasswordForm()) {
frm.ShowDialog();
}

Combine this with a DialogResult:

private void bCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}

Setting the DialogResult, will close the Dialog, and the caller/owner has some feedback.

And you don't have to worry about Close or Dispose.



Related Topics



Leave a reply



Submit