方法1,设置flag. 这个方法是最平常的了 ,没什么好说的,但不是最佳的选择,因为当窗口多了,难道每个窗口都在配一个flag吗?故鄙人推荐下面的方法。
方法2
主窗口
public partial class MainForm : Form { public static MessageReplyer m_messageReply = null; public MainForm() { InitializeComponent(); } private void toolStripButton1_Click(object sender, EventArgs e) { if (m_messageReply == null) { m_messageReply = new MessageReplyer(); m_messageReply.MdiParent = this; m_messageReply.Show(); } else { m_messageReply.Activate(); } } }
子窗口
public partial class MessageReplyer : Form { public MessageReplyer() { InitializeComponent(); } private void MessageReplyer_FormClosed(object sender, FormClosedEventArgs e) { MainForm.m_messageReply = null; } }
看到网上有一个解决方案和此方案差不多,但那个解决方案存在漏洞。我解决漏洞的方案就是在关闭form的同时将其变量的值置为null。
当然这又牵扯到另一系列的问题:
有人会问为什么置为null不放在类的析构函数中,这样多省事啊,自动析构。通常我们在c++中会放在类的析构函数中,但C#却不行。原因在于:
在c#中析构函数并不保证同步被调用,而是由垃圾回收器在后台被调用.
MSDN中建议不要在析构函数中执行与内存不相关的资源回收或时间较长的工作
析构函数只有在GC回收时才调用,在调试环境也是无法跟踪的
析构函数就是破坏者,只在垃圾回收时被显式调用的.C++对正确编写析构函数很重要,但是C#有垃圾自动回收机制,所以一般类中都不使用析构函数.
- C# code
-
public class Component { //... public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); //<--- } }
当窗口程序结束时,Form1被Diposed了。
当Form(Form继承自Component)被Disposed的时候,GC.SuppressFinalize要求CLR不用再调用Finalizer。
.NET中不建议使用析构函数...Component类应在Disposed事件中释放资源,Form类应在更高级的Closed事件中释放资源...对自定义的类应继承IDisposable接口并在Dispose方法中释放资源...
solution:当前情况,应该使用Closed事件进行资源回收和相关窗口关闭前的处理工作。