2013-02-12 48 views
1

這可能看起來像一個愚蠢的問題,但我只是想確保我的工作是正確的。我的主要形式大多數時間不可見。要打開它,我有一個NotifyIcon。其中一個菜單選項是退出應用程序。我還有一些靜態全局變量需要在應用程序關閉之前處理掉。所以在program.cs中我有這個。關閉來自不同表格的WinForm應用程序

[STAThread] 
    static void Main() 
    { 
     InitializeApplication(); 
     InitializeMainForm(); 
     Application.Run(main); 
    } 
    private static void InitializeApplication() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.ApplicationExit += Application_ApplicationExit; 
    } 
    private static void InitializeMainForm() 
    { 
     main = new AssignButtonForm(); 
     main.FormClosing += main_FormClosing; 
     Globals.StartNotify(); 
    } 

    static void main_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     var dlg = MessageBox.Show("Turn off Application?", "Exit?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); 
     if (dlg == DialogResult.OK) 
     { 
      Globals.notifyIcon1.Dispose(); 
      Application.Exit(); 
     } 
     else 
     { 
      e.Cancel = true; 
     } 
    } 

所以我希望是這是正確的方式來調用。

private void exitToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     this.Hide(); 
     Application.OpenForms[0].Close(); 
    } 

是否正確?或者,還有更好的方法?

編輯

確定我的課,這樣一個有自己的Dispose方法

public class KeymonNotifyIcon : IDisposable 
{ 
    public KeymonNotifyIcon() 
    { 
     InitializeComponent(); 
     keymonMenuStrip.SetupKeysSelected += OnSetupKeysSelected; 
    } 
    ~KeymonNotifyIcon() 
    { 
     Dispose(); 
    } 
    public void Dispose() 
    { 
     if (notifyIcon1 != null) 
      notifyIcon1.Dispose(); 

     if (keymonMenuStrip != null) 
      keymonMenuStrip.Dispose(); 
    } 
} 

全球一流

public static class Globals 
{ 
    public static TraceSource trace = new TraceSource("Keymon"); 
    public static KeymonNotifyIcon notifyIcon1; 
    public static void StartNotify() 
    { 
     notifyIcon1 = new KeymonNotifyIcon(); 
    } 
} 

回答

1

如果你的程序只是關機,還沒有被垃圾回收將有自己的終結運行對象。實施IDisposable的對象具有確定運行IDisposable的終結器recommended pattern。就我所知,.NET BCL類總是遵循這種模式。但是,您自己的或第三方/開源組件可能不遵循該模式。

注意:MSDN上的鏈接模式不會調用GC.SuppressFinalize。檢查出how to use it以減少GC開銷。

單獨實施IDisposable不足以確保對象正確處置。

如果您有靜態引用的實現IDisposable的對象,那麼從應用程序關閉事件中明確地調用IDisposable.Dispose()是更穩固的解決方案。

編輯

你處置的實施將導致Dispose()方法進行兩次在所擁有的對象調用,因爲:

if (notifyIcon1 != null) 
     notifyIcon1.Dispose(); 

不設置notifyIcon1null,並終結無條件再次呼籲Dispose()

此外,您將永遠事業終結運行(這使得GC更昂貴的是類),因爲你不Dispose()調用GC.SuppressFinalize()

2

實際上,我相當肯定,Application.Exit將調用你所有的Dispose方法(只要你已經實施IDisposable

this question,它引用this question

+0

所有這些?即使那些不屬於全局靜態類中主表單的部分?(請參閱編輯後的文章) – 2013-02-12 17:51:05

+0

如果您已經實現了'IDisposable' – 2013-02-12 17:51:39

+0

如果您想確保處理所有內容,則可以在您的'OnFormClosing'事件中放置一個Dispose-Method。 但這不應該是必要的! – jAC 2013-02-12 17:54:32

相關問題