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 whenClose()
is called.However, if you do
form1.ShowDialog()
to show the form modally, the form
will not be disposed, and you'll need
to callform1.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:
- You have a global Timer instance
- You create form2
- Form2 subscribes to the timer
- Form2 is Closed and/or Disposed
- The Timer event fires, increments the counter and shows a MessageBox
- 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.
- Don't do this (give Form2 it's own timer)
- 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
Export Datatable to Excel File
Hashing Passwords with Md5 or Sha-256 C#
Differencebetween Bool and Boolean Types in C#
How to Get the Name of the Current Executable in C#
What Does |= (Single Pipe Equal) and &=(Single Ampersand Equal) Mean
Is There an Alternative to Bastard Injection? (Aka Poor Man's Injection via Default Constructor)
How to Upload a File to a Document Library in Sharepoint
Pass Parameter to Eventhandler
Using Process.Start() to Start a Process as a Different User from Within a Windows Service
Best Way to Call a JSON Webservice from a .Net Console
Entity Framework 6 Transaction Rollback
Check If a String Contains an Element from a List (Of Strings)
Fast Way to Convert a Two Dimensional Array to a List ( One Dimensional )