Closing all forms in an application seems like it would be a simple task of using a foreach loop in the Application.OpenForms collection, such as:
foreach (Form form in Application.OpenForms)
{
form.Close();
}
But there are two problems.
First, the code above will throw an exception because the OpenForms collection changes each time you close a form, and so the enumerator in your foreach loop becomes invalid when you close a form. Instead, you need to get an array of all open forms, then loop through the array:
static public void CloseAllForms()
{
// get array because collection changes as we close forms
Form[] forms = OpenForms;
// close every open form
foreach (Form form in forms)
{
CloseForm( form );
}
}
Second, it’s quite possible that your application opened one or more forms in a separate thread. If so, then trying to close a form from your main thread will throw an exception. So you need to close your forms in a thread-safe manner:
delegate void CloseMethod( Form form );
static private void CloseForm( Form form )
{
if (!form.IsDisposed)
{
if (form.InvokeRequired)
{
CloseMethod method = new CloseMethod( CloseForm );
form.Invoke( method, new object[] { form } );
}
else
{
form.Close();
}
}
}
Download a C# WinForms project that demonstrates how to close all Forms in a C# application in a thread-safe manner.
Popularity: 27% [?]
Related posts:


Awesome, thanks!
Learned something new!
Sound good but this statement doesn't pass the compiler
Form[] forms = OpenForms;
I get an error said can not implicitly convert Applicaton form collection to System.Windows.Forms
Yes, I see how that can be confusing. OpenForms in the second example is a static method that I wrote which returns an array of open forms (versus Application.OpenForms which returns a collection). Download the example, but here is the code:
public static Form[] OpenForms
{
get
{
Form[] forms = null;
int count = Application.OpenForms.Count;
forms = new Form[count];
if (count > 0)
{
int index = 0;
foreach (Form form in Application.OpenForms)
{
forms[index++] = form;
}
}
return forms;
}
}
its a lot more simple to just use the FormCollection, since that is what Application.OpenForms uses
FormCollection forms = Application.OpenForms;
for( int i = 0; i < forms.Count; i++ ) {
forms[i].Close();
}
Ryan, if you read the article, that doesn't work because closing the form modifies the collection, which then throws an exception while iterating.
Thanks, i was having trouble closing a form created on a separate thread and this has solved it!
I Guess this code is very simple compare to the above solutions.
public static void CloseAllForms()
{
//Create a Collection to Store all Opened Forms.
List formsList = new List();
//All all opened forms into a Collection.
foreach (Form frm in Application.OpenForms)
{
//Execulde the Current Form.
if (frm.Name == "Form1″)
continue;
else
formsList.Add(frm);
}
//Now Close the forms
foreach (Form frm in formsList)
{
frm.Close();
}
}
I don't think this solution is thread-safe either. Think about what happens if Application.OpenForms is modified by another thread opening or closing a form, while the static OpenForms property's get accessor is iterating through the foreach statement? The OpenForms collection would be altered between iterations of the foreach, which causes a runtime exception. Similar problems plague a simple for statement.
If you want true thread safety, then the OpenForms property will need to be wrapped in a lock(Application.OpenForms) statement. Any other places in your application that open or close a form will likewise need to lock the same object.
Nice article… n learn a nice technique.
[...] Second, it’s quite possible that your application opened one or more forms in a separate thread. If so, then trying to close a form from your main thread will throw an exception. So you need to close your forms in a thread-safe manner: view source [...]
This is a modified version of one of the above, might be useful to someone.
Public Sub CloseAllForms()
'Create a Collection to Store all Forms.
Dim FormList As ArrayList = New ArrayList()
'Add all opened forms into a Collection.
For Each Frm In Application.OpenForms
FormList.Add(Frm.name)
Next
'Now Close the forms
For Each FormName In FormList
Application.OpenForms(FormName).Close()
Next
End Sub