[C#][WinForm]Application.Exit關閉應用程式後真的不執行了嗎?

[C#][WinForm]Application.Exit關閉應用程式後真的不執行了嗎?

一般如果想關閉整個應用程式,自己大部分都會使用Application.Exit來處理

MSDN中文解釋:通知所有必須結束的訊息幫浦,接著在訊息處理完成之後關閉所有應用程式視窗。

(自己覺得MSDN解釋有點模糊)

所以這裡我將和Environment.Exit方法來做個小小測試,順便記錄一下。

 

執行測試應用程式

image


private void Form1_Load(object sender, EventArgs e)
        {            
            Thread myThread = new Thread(new ThreadStart(mywork));
            myThread.IsBackground = true;//背景執行緒
            myThread.Start();           
        }

delegate void MyInvoke(String status);
        private void UpdateLab(String status)
        {
            label1.Text = status;
        }

 private void mywork()
        {
            try
            {
                for (int i = 0; i < 100000000; i++)
                {
                    MyInvoke mi = new MyInvoke(UpdateLab);
                    //使用主緒更新Label  
                    Invoke(mi, i.ToString());
                    Thread.Sleep(1);
                }
            }
            catch (ObjectDisposedException) { }                       
        }

測試關閉方法(多加了Application.ExitThread),在每種方法後執行開啟IE視窗工作。


private void appexit_Click(object sender, EventArgs e)
        {
            Application.Exit();
            Log(0);
        }

        private void enviexit_Click(object sender, EventArgs e)
        {
            Environment.Exit(Environment.ExitCode);
            Log(1);
        }

        private void appexitthread_Click(object sender, EventArgs e)
        {
            Application.ExitThread();
            Log(2);
        }

private void Log(Int32 method)
        {
            String MethodName = String.Empty;
            switch (method)
            { 
                case 0:
                    MethodName = "Application.Exit";
                    break;
                case 1:
                    MethodName = "Environment.Exit";
                    break;
                case 2:
                    MethodName = "Application.ExitThread";
                    break;
            }
            Thread LogThread = new Thread(new ParameterizedThreadStart(WriteLog));
            LogThread.IsBackground = true;//背景執行緒
            LogThread.Start(MethodName);
            Process.Start("IExplore.exe", "tw.yahoo.com");//開啟IE視窗       
        }

private void WriteLog(object method)
        {
            FileStream fs = new FileStream(@"c:\mytestlog.log", FileMode.OpenOrCreate|FileMode.Append, FileAccess.Write);
            StreamWriter logsw = new StreamWriter(fs);
            /*for (Int32 i = 0; i < 100000; i++)
            {
                logsw.Write(i.ToString());
            }
            logsw.Write(Environment.NewLine);*/ 
            logsw.Write("{0} 關閉方法:{1}", DateTime.Now.ToLongTimeString(), method + Environment.NewLine);         
            logsw.Close();
            fs.Close();           
        }

結果如下:

Application.Exit雖然UI都關閉了,但還是會執行應用程式後續工作(Application.ExitThread也是)。

image

Environment.Exit在UI關閉後,不會執行應用程式後續工作,算強制中斷所有工作。

 

結論:

Application.Exit:會通知應用程式停止相關的訊息(all threads),並等待訊息執行完成後關閉應用程式(all UI),

但這只保證訊息是在Application.Exit才能被停止,Application.Exit的訊息是無法被停止的,

所以後續工作仍會佔用系統資源,直到相關工作結束為止。

Application.ExitThread:結束目前執行緒的訊息迴圈,並關閉執行緒上的所有視窗,所以不會引發Form.Closed和Form.Closing事件。

Environment.Exit:不等待相關訊息的結束,強制退出應用程式。

所以個人認為,正確的退出應用程式,應在Form.Closing事件中循環處理停止每個訊息工作,

並在Form.Closed事件中加入Environment.Exit會來的比較保險點。


private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Close();
            Environment.Exit(Environment.ExitCode);           
        }

 

參考

Application.Exit

Application.ExitThread

Environment.Exit