[C# ] 關閉應用程式指令比一比 Application.Exit,Application.ExitThread,Environment.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);           
        }
轉自 : https://dotblogs.com.tw/ricochen/2010/01/18/13066

留言

熱門文章