从不同的窗体关闭WinForm应用程序
本文关键字:WinForm 应用程序 窗体 | 更新日期: 2023-09-27 17:58:54
这个问题可能看起来很傻,但我只想确保我说得对。我的主窗体大部分时间都不可见。要打开它,我有一个NotifyIcon。其中一个菜单选项是"退出应用程序"。我还有一些静态全局变量需要在应用程序关闭之前处理掉。所以在程序.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()
。
此外,由于您没有在Dispose()
中调用GC.SuppressFinalize(),因此总是导致终结器运行(这使GC对该类来说更昂贵)。