事件是否保证会发生

本文关键字:是否 事件 | 更新日期: 2023-09-27 17:57:13

假设我有一个从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
}

我想在窗体关闭时显示该消息框。 我应该把它贴在 FormClosed 事件中吗? 假设每次运行析构函数之类的内容时都会触发 FormClosed 事件是否安全? 有没有更好的位置来放置关闭表单时必须发生的代码?

编辑

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

我也知道,强制关闭系统、结束进程、天灾等无论如何都不会导致我的代码运行。 =)

事件是否保证会发生

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

  1. 将变量设置为 null(不调用 Close 方法)
  2. 另一个委托中的异常:所有事件都MulticastDelegate s,并且委托按在该MulticastDelegate中出现的顺序执行,如果前面的委托之一导致异常,则不会调用您的委托。

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

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

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

看起来真的没有办法保证代码将从表单中调用。 您可以将代码放在Application.Run();之后Main(),它就会在那里被调用。 还有一个Application.ApplicationExit事件,除非您有特殊情况(强制关闭或崩溃),否则会被调用。

您可以在窗体中为 Application.ApplicationExit 事件注册处理程序,但请注意,此时您的对象已被释放,因此您无法对其进行任何操作。

FormClosed 事件由 OnClosed 方法引发。因此,如果您想要一定程度的保证,则可以覆盖OnClosed方法。