Application.Exit

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



Leave a reply



Submit