事件是否有保障?

时间:2011-05-20 17:20:36

标签: c# .net events

假设我有一个继承自Form的表单SomeForm。

public class SomeForm : Form
{
    private void SomeForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        MessageBox.Show("FormClosed event in SomeForm class");
    }
}

public class Consumer
{
    SomeForm someForm = new SomeForm();
    someForm = null; //Ideally the messagebox would display here
    SomeForm someForm = new SomeForm();
    someForm.Close();  //Messagebox would display in this case as well
}

我想在窗体关闭时显示MessageBox。我应该坚持在FormClosed事件中吗?假设每次运行类似析构函数的事件时,FormClosed事件都会触发,这是否安全?是否有更好的地方放置表单关闭时必须出现的代码?

修改

有人在下面的评论中提出了一个很好的观点。当类的实例设置为null时,似乎事件不会触发。但是,当实例设置为null时,是否仍会调用析构函数或其他方法。我想保证我的代码在用户完成该类时运行。

我也知道强行关闭系统,结束这个过程,上帝的行为等都不会导致我的代码无论如何运行。 =)

3 个答案:

答案 0 :(得分:4)

是的,除非发生异常情况,否则将调用它,例如通过系统命令或拔出插头来杀死它。其他案例包括

  1. 将变量设置为null(不调用Close方法)
  2. 另一个委托中的异常:所有事件都是MulticastDelegate,并且代理按照MulticastDelegate中的外观顺序执行,如果您之前的一个前任代表导致异常,您的代表将不被召唤。

答案 1 :(得分:1)

除非您的可执行文件被强制关闭(通过任务管理器或命令行中的taskkill)或程序崩溃,否则将被调用。

编辑:我做了一些实验,发现了以下内容:

  • 如果您将对表单的引用设置为null,则表单仍然可见,并且当表单关闭时,事件将被引发。
  • 如果您的表单是子表单并且主表单已关闭,子表单将关闭而不会引发事件。
  • 如果您调用表单的Hide()方法,则不会引发该事件。随后关闭主表单,如上所述,不会导致事件被提升。
  • 覆盖OnClosed()无济于事,因为如果主窗体已关闭,它仍然无法调用。
  • 调用表单的Dispose()方法(如果没有指向它的话,GC最终会做什么)也不会导致事件被提升。

看起来确实没有办法让GUARANTEE从表单中调用代码。您可以将Application.Run();中的代码放在Main()中,然后在那里调用它。除非您有特殊情况(强行关闭或崩溃),否则还会有Application.ApplicationExit被调用的事件。

您可以在表单中注册Application.ApplicationExit事件的处理程序,但请注意,此时您的对象已被处理掉,因此您无法对其执行任何操作。

答案 2 :(得分:0)

FormClosed事件由OnClosed方法引发。因此,如果您需要某种级别的保证,可以覆盖OnClosed方法。