Application.Exit
Application.Exit
really just asks the message loop very gently.
If you want your app to exit, the best way is to gracefully make it out of Main
, and cleanly close any additional non-background threads.
If you want to be brutal... Environment.Exit
or Environment.FailFast
? note this is harsh - about the same as killing your own Process
.
Winforms Application.Exit on Closing x app or clicking a Exit Button with a confirmation message
Thanks to nihique posted here https://stackoverflow.com/a/13459878/942855
and also pointed by MickyD in this question comments.
Apparently there is no issue with my closing event. When I redirect from Form-A to Form-B, I had to do the following wiring and then it worked like a charm
var newform = new myNewForm();
newform.Closed += (s, args) => this.Close();
this.Hide();
newform.Show();
How do I properly exit a C# application?
From MSDN:
Application.Exit
Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed. This is the code to use if you are have called Application.Run (WinForms applications), this method stops all running message loops on all threads and closes all windows of the application.
Environment.Exit
Terminates this process and gives the underlying operating system the specified exit code. This is the code to call when you are using console application.
This article, Application.Exit vs. Environment.Exit, points towards a good tip:
You can determine if System.Windows.Forms.Application.Run
has been called by checking the System.Windows.Forms.Application.MessageLoop
property. If true, then Run has been called and you can assume that a WinForms application is executing as follows.
if (System.Windows.Forms.Application.MessageLoop)
{
// WinForms app
System.Windows.Forms.Application.Exit();
}
else
{
// Console app
System.Environment.Exit(1);
}
Reference: Why would Application.Exit fail to work?
Application.Exit() not working properly
The code inside Music_FormClosing
is preventing your application from exiting. To get the desired behavior (prevent the user closing the music form), you can utilize the FormClosingEventArgs
CloseReason
property:
private void Music_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
e.Cancel = true;
}
Winforms: Application.Exit vs Environment.Exit vs Form.Close
The proper method would be Application.Exit()
. According to the Documentation, it terminates all message loops and closes all windows thus giving your forms the possibility to execute their cleanup code (in Form.OnClose etc).
Environment.Exit
would just kill the process. If some form has e.g. unsaved changes it would not have any chances to ask the user if he wants to save them. Also resources (database connections etc.) could not be released properly, files might not be flushed etc.
Form.Close
just does what it says: it closes a form. If you have other forms opened (perhaps not now but in some future version of your application), the application will not terminate.
Keep in mind that if you use multithreading, Application.Exit()
will not terminate your threads (and thus the application will keep working in the background, even if the GUI is terminated). Therefore you must take measures to kill your threads, either in the main function (i.e. Program.Main()
) or when in the OnClose
event of your main form.
C# Application Exit with Mutex
If you want to create a singleton application, you cannot implement the Mutex
logics in AppForm_Load
because when you reach that point (which is not the entri point / main method of your assembly), it means your application has already been started. With your implementation you can at best close the new instance once you notice that another one, previously created, is already running... why not "preventing" the creation of a new instance directly?
This is my template for singleton applications (the Program
class a the static class that contains my application entry point static void Main
):
#region Using Directives
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
#endregion
namespace MyNamespace
{
public static class Program
{
#region Members: Static
private static Int32 s_MutexMessage;
private static Mutex s_Mutex;
#endregion
#region Properties: Static
public static Int32 MutexMessage
{
get { return s_MutexMessage; }
}
#endregion
#region Methods: Entry Point
[STAThread]
public static void Main()
{
Assembly assembly = Assembly.GetExecutingAssembly();
String assemblyGuid = ((GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;
String mutexName = String.Format(CultureInfo.InvariantCulture, "Local\\{{{0}}}", assemblyGuid);
s_MutexMessage = NativeMethods.RegisterWindowMessage(assemblyGuid);
Boolean mutexCreated;
s_Mutex = new Mutex(true, mutexName, out mutexCreated);
if (!mutexCreated)
{
NativeMethods.PostMessage((new IntPtr(0xFFFF)), s_MutexMessage, IntPtr.Zero, IntPtr.Zero);
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ApplicationForm());
s_Mutex.ReleaseMutex();
}
#endregion
}
}
Then, within the form class (which is ApplicationForm
in my example):
protected override void WndProc(ref Message m)
{
if (m.Msg == Program.MutexMessage)
{
if (NativeMethods.IsIconic(Handle))
NativeMethods.ShowWindow(Handle, 0x00000009);
NativeMethods.SetForegroundWindow(Handle);
}
base.WndProc(ref m);
}
Finally, for the sake of completeness, here are the importations that my code use, located within the NativeMethods
class (remember to mark it as internal
, it's a good practice that should not be neglected):
internal static class NativeMethods
{
#region Importations
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean IsIconic([In] IntPtr windowHandle);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean PostMessage([In, Optional] IntPtr windowHandle, [In] Int32 message, [In] IntPtr wParameter, [In] IntPtr lParameter);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean SetForegroundWindow([In] IntPtr windowHandle);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean ShowWindow([In] IntPtr windowHandle, [In] Int32 command);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)]
internal static extern Int32 RegisterWindowMessage([In] String message);
}
This implementation is a little bit longer than the traditional one based only on a Mutex
object, needs a wide usage of native interop and must be splitted among different classes within your project... but I use it template since long long time ago and I can affirm that it's bulletproof.
Application.exit() calls FormClosingEvent of different Windows Form
Create a new class something like
public static class ApplicationCloseHelper
{
public static void CloseApplication()
{
if (UserIsSure())
{
Application.Exit();
}
}
private static bool UserIsSure()
{
string exitMessageText = "Are you sure you want to exit the application?";
string exitCaption = "Cancel";
MessageBoxButtons button = MessageBoxButtons.YesNo;
DialogResult res = MessageBox.Show(exitMessageText, exitCaption, button, MessageBoxIcon.Exclamation);
return res == DialogResult.Yes;
}
}
then remove the Form_Closing
event handlers and call
ApplicationCloseHelper.CloseApplication();
directly from Cancel_Click();
Application.Exit Isn't closing my program, any alternatives?
You want:
Environment.Exit(0);
Capturing Application exit event - WinForms
In Program.cs file, you must have those methods before Application.Run :
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
Application.Run(new MainForm());
}
You can also use the Disposed event on the MainForm (the form used in Application.Run method).
Related Topics
Retrieve System Uptime Using C#
Change Values in JSON File (Writing Files)
How to Run a Task on a Custom Taskscheduler Using Await
The Input Is Not a Valid Base-64 String as It Contains a Non-Base 64 Character
How to Read Attribute Value from Xmlnode in C#
C# - Detect Time of Last User Interaction with the Os
Appsettings Get Value from .Config File
Failed to Serialize the Response in Web API
What Is Quicker, Switch on String or Elseif on Type
How to "Flatten" or "Index" 3D-Array in 1D Array
Double Buffering When Not Drawing in Onpaint(): Why Doesn't It Work
Appending an Existing Xml File with Xmlwriter
Using the "Params" Keyword for Generic Parameters in C#
Why Can't I Use System.Io.File Methods in an MVC Controller
Parsing CSV Using Oledb Using C#
How to Ensure a Form Displays on the "Additional" Monitor in a Dual Monitor Scenario