簡體   English   中英

從不同的表單關閉WinForm應用程序

[英]Close WinForm Application from different Form

這似乎是一個愚蠢的問題,但我只是想確保我做對了。 我的主要形式大部分時間都不可見。 要打開它,我有一個NotifyIcon。 其中一個菜單選項是Exit Application。 我還有一些靜態全局變量需要在應用程序關閉之前處理掉。 所以在program.cs我有這個。

    [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();
    }
}

實際上,我相當確定Application.Exit會為你調用所有的Dispose方法(只要你實現了IDisposable

請參閱此問題該問題引用了此問題

如果您的程序剛剛關閉,那些未被垃圾回收的對象將運行其終結器 推薦的模式是實現IDisposable對象具有終結器以確保運行IDisposable 據我所知,.NET BCL類始終遵循該模式。 但是,您自己的或第三方/開源組件可能不遵循該模式。

注意:MSDN上的鏈接模式不會調用GC.SuppressFinalize。 了解如何使用它來減少GC開銷。

單獨實現IDisposable不足以確保正確處理對象。

如果您有靜態引用的實現IDisposable對象,那么從應用程序關閉事件中顯式調用IDisposable.Dispose()是一個更可靠的解決方案。

編輯

您的Dispose實現將導致Dispose()在擁有的對象上被調用兩次,因為:

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

不將notifyIcon1設置為null ,並且終結器無條件地再次調用Dispose()

此外,您將始終使終結器運行(這使得該類的GC更加昂貴),因為您不在Dispose()調用GC.SuppressFinalize Dispose()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM