1

これはばかげた質問のように思えるかもしれませんが、私はそれが正しいことを確認したいだけです. ほとんどの場合、メイン フォームは表示されません。それを開くには、NotifyIcon があります。メニュー オプションの 1 つに [アプリケーションの終了] があります。また、アプリケーションを閉じる前に破棄する必要があるいくつかの静的グローバル変数もあります。だから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 メソッドを持つクラスの 1 つ

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

2 に答える 2

2

実際、私はあなたのためにあなたApplication.Exitのすべてのメソッドを呼び出すとかなり確信してDisposeいます(あなたが実装している限り)IDisposable

この質問を参照するこの質問を参照してください

于 2013-02-12T17:48:51.673 に答える
1

プログラムがシャットダウンしたばかりの場合、ガベージコレクションされていないオブジェクトはファイナライザーを実行します。実装するオブジェクトにファイナライザーを設定して、それが確実に実行されるようにすることをお勧めします。私の知る限り、.NETBCLクラスは常にそのパターンに従います。ただし、独自のコンポーネントまたはサードパーティ/オープンソースコンポーネントは、そのパターンに従わない場合があります。IDisposableIDisposable

注:MSDNのリンクされたパターンは、GC.SuppressFinalizeを呼び出しません。GCのオーバーヘッドを減らすためにそれを使用する方法を確認してください。

IDisposableオブジェクトを適切に配置するには、実装だけでは不十分です。

を実装する静的に参照されるオブジェクトがある場合は、アプリケーションのシャットダウンイベントからそれらIDisposableを明示的に呼び出す方がより確実なソリューションです。IDisposable.Dispose()

編集

Disposeの実装により、所有されているオブジェクトに対してDispose()が2回呼び出されます。理由は次のとおりです。

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

はに設定されずnotifyIcon1nullファイナライザーは無条件Dispose()に再度呼び出します。

さらに、でGC.SuppressFinalize()を呼び出さないため、常にファイナライザーを実行します(これにより、そのクラスのGCのコストが高くなります) 。Dispose()

于 2013-02-12T18:03:01.917 に答える