【问题标题】:Are events guaranteed to go off?活动是否保证会举行?
【发布时间】:2011-08-29 20:22:15
【问题描述】:

假设我有一个继承自 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 事件是否安全?有没有更好的地方放置表单关闭时必须出现的代码?

编辑

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

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

【问题讨论】:

  • 您的问题肯定有答案。但是,将时间花在解决您认为可以通过触发这些事件来解决的任何问题上不是更好吗?
  • define “完成了课程” - 你仍然有太多的空缺。作为第一步,描述您正在处理/考虑的一个具体场景,以及您确定的任何其他场景。
  • @Damien_The_Unbeliever 我的问题来自理论讨论。它只是让我质疑事件的可靠性。
  • 如果您出于安全原因或完整性原因依赖事件,那么您需要重新审视这些决定。除此之外,我想不出你为什么要要求一个事件发生。

标签: c# .net events


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 如果SomeForm 实例设置为null 或重新实例化怎么办?
  • 它没有关闭,因此没有调用事件。
  • 我承认这是一个有点做作的情况,但 OP 确实问过“是否可以安全地假设每次运行析构函数之类的东西都会触发 FormClosed 事件?”
【解决方案2】:

FormClosed 事件由 OnClosed 方法引发。所以如果你想要一定程度的保证,你可以重写 OnClosed 方法。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2016-10-19
      • 2012-03-06
      • 1970-01-01
      相关资源
      最近更新 更多