WPF 退出程序 C# :如何優雅地退出WPF應用程序

C# :如何優雅地退出WPF應用程序

 

前言html

I should know how I am supposed to exit my application when the user clicks on the Exit menu item from the File menu. 或者點擊window右上角的X退出應用。python

可是退出應用程序時,應該考慮到哪些點呢?程序員

(1)有人認爲在關閉應用前,應該觸發一個確認窗口,指示用戶是否確認退出,由於if there are jobs running, the force exit will cause damages, so we better to let them informed in the confirmation dialog。express

(2)有人認爲太多的確認是一件很是糟糕的事情。事實上,有人花了點擊打開文件菜單,一直向下移動到文件菜單的底部,而後單擊退出,幾乎確認他們再也不但願使用該應用程序。windows

其實就我來看,上面兩類觀點都有道理,關鍵是要適合本身的狀況。(This is better to be designed case by case,此話老套而不過期)app

如何根據實際狀況進行權衡,就是本文要討論的如何優雅地退出應用程序的問題,只不過這裏只針對WPF應用而言。post

 

正文測試

做爲一個程序員,咱們先關注下實現exit application的技術。this

  • 首先,咱們可能想到使用:
Application.Current.Shutdown();

(注:Application.Current.Shutdown(); 只能從建立Application對象的線程調用,即一般是主線程)url

我作過測試,在MainWindow中,我觸發了其餘幾個windows,而後在MainWindow的window_closed事件中,我添加了該代碼,全部的窗口都消失了,但後臺程序仍舊在運行。

這是爲何呢?

其實,全部其餘owned窗口會被關閉,但你必須確保聲明全部權。若是你有一個正在運行的窗口,而後打開另外一個窗口但還沒有顯示,則在關閉活動窗口後,隱藏的窗口將強制應用程序繼續運行。除非你經過其餘方式(任務管理器等)關閉該窗口,不然將會有潛在的內存泄漏。

另外值得注意的是:Application.Current.Shutdown();是不可逆轉的,它一般用於強制應用程序關閉,例如用戶註銷或關閉Windows時。Instead, 在主窗口中調用this.close(), 這與按「ALT-F4」或窗口上的關閉[x]按鈕做用相同。這將致使全部其餘全部的窗口關閉,並將最終調用Application.Current.Shutdown();只要關閉動做未被取消。可參閱關閉窗口的MSDN文檔。

另外,因爲this.close()能夠取消,你能夠在關閉事件處理程序中放入保存更改確認對話框。只須要構建<Window Closing =「...」>的事件處理程序,並相應地更改e.Cancel的值(true or false)。

 

  • 其次,若是你真的須要關閉應用程序,你也可使用Environment.Exit(),但它並不優雅(更像是結束進程):
Environment.Exit(0)

Environment.Exit()至少須要一個參數,一個退出代碼。若是你不關心退出代碼,就像上面那麼用。

Environment.Exit is definitely the right way to ensure shutdown of an application. With Application.Current.Shutdown you can easily end up with the application running on indefinitely if you have code that pushes itself back into the dispatcher. 意思就是說這絕對是確保關閉應用的正確方式。使用Application.Current.Shutdown,當你的代碼中有回調自身的狀況時,很容易出現程序無限運行的結果。

注:與Application.exit(0);同等效果。

 

 

代碼實例:

MainWindow.xaml中windows部分詳情以下:

1
2
3
4
5
6
7
8
9
<Window
         xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local= "clr-namespace:Application"       
         mc:Ignorable= "d"
         
         Title= "Application"  Height= "1050"  Width= "1800"  Closing= "Window_Closing"  Icon= "Images/app_icon.png"  Loaded= "Window_Loaded" >

 MainWindow.xaml.cs關鍵部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Any control that causes the Window.Closing even to trigger.
private  void  MenuItem_Exit_Click( object  sender, RoutedEventArgs e)
{
     this .Close();
}
 
// Method to handle the Window.Closing event.
private  void  Window_Closing( object  sender, System.ComponentModel.CancelEventArgs e)
{
     try
    {
         MessageBoxResult msgBoxResult = MessageBox.Show( "Do you really want to exit?" "Exiting..." , MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
 
         if  (msgBoxResult == MessageBoxResult.No)
         {
             e.Cancel =  true ;
             return ;
         }
         else
         {
             var  jobState = XXX.GetJobState();
             if  (jobState == finished || ...)
             {
                 e.Cancel =  false ;
             }
             else
            {
                 MessageBox.Show( "Application is running job, please wait till finish. " );
                 e.Cancel =  true ;
                 return ;
             }
         }
 
         //to do something Uninitialize or ...
             
     }
     catch  (Exception ex)
     {
         XXX.LogError(appName, ex);
     }
 
     CloseChildWindows();
}
 
 
private  void  CloseChildWindows()
{
     if  (pythonWindow !=  null )
     {
         pythonWindow.Closed -= ChildWindowClosed;
         pythonWindow.Close();
         pythonWindow =  null ;
     }
 
     ......
}         

注:該部分一些方法或變量是模擬的。

相關文章
相關標籤/搜索