Proper way to dispose a new Form
Do I need to Dispose a Form after closing the Form?
When you show the form using Show()
you don't need to dispose it, because it will dispose after close. But when you show form using ShowDialog()
, you need to dispose the form, because it won't dispose after closing.
When you close a Form
, a WM_CLOSE
message will be sent to the window. If you take a look at source code of WmClose
method which handles WM_CLOSE
message, you will see:
For modal forms (which you showed using
ShowDialog
), theDispose
method will not be called and the form exists after closing and you can use its properties to get some data or you can show it again.For non-modal forms (which you showed using
Show
), after the form got closed, theDispose
method will be called.
So here is the conclusion:
When you show a form using
Show
method you don't need to (and you can't) callDispose
. The form will be disposed itself after got closed.When you show a form using
ShowDialog
you need to callDispose
manually. A good practice is use modal forms in ausing
block.
Example
To show a modal dialog, as a best practice use a using
block:
//form will be disposed after the using block
using (var f = new MyForm())
{
if (f.ShowDialog() == DialogResult.OK)
{
//Your logic to handle OK here
}
}
For a non-modal dialog, show and forget about it:
var f = new MyForm();
f.Show();
You could implement somekind of forms manager that will subscribe to the OnFormClosedEvent for each form it shows, it can then dispose them... something like:
public class FormManager
{
public T ShowForm<T>()
where T : Form, new()
{
var t = new T();
t.OnFormClosing += DisposeForm;
return t;
}
void DisposeForm(object sender, FormClosedEventArgs args)
{
((Form)sender).Dispose();
}
}
You could even go so far as to implement IDisposable and dispose all non-disposed forms when the manager is disposed :)
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.