代码之家  ›  专栏  ›  技术社区  ›  JYelton Melchior Blausand

关闭WinForms的最佳实践:清理和最后一分钟的应用程序事件

  •  4
  • JYelton Melchior Blausand  · 技术社区  · 14 年前

    我有各种小型C WinForms应用程序(尽管这同样适用于任何.NET应用程序),它们在关闭时需要执行一些小任务。

    我一直在利用 .FormClosing 事件执行诸如写入当前设置文件和等待后台线程完成等操作。

    就最佳实践而言,我们想到了两个问题:

    • 关闭表单时是否需要停止计时器(或类似任务)?知道终止应用程序应该处理计时器,发出 timer.Stop() 在表格的结尾?一旦进入 关闭 计时器可以再次触发的方法?

    • 最后一分钟的任务(如写入设置文件)是否应位于 关闭 .FormClosed 事件(或其他地方)和原因?

    很抱歉合并了这些问题,但我觉得它们之间的关系非常密切,足以保证一个关于正确关闭基于表单的应用程序的线程。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Henk Holterman    14 年前

    我应该停止计时器吗?

    不是真的,但也不会疼。

    关闭窗体后是否可以触发计时器?

    狡猾的通常不会,但如果关闭链中的某些代码调用application.doEvents(),我不会排除这种可能性。总是一个好主意,以防御方式编程您的计时器处理程序。

    最后一分钟的任务应该是.formClosing还是.formClosing?

    FormClosing是有条件的,它的主要功能是显示“先保存?”盒子或类似的。我会把所有东西都放在FormClosed中,除非它确实需要更早(即它需要其他组件/控件处于活动状态)。

        2
  •  4
  •   Hans Passant    14 年前

    保证单线程

    好吧,您已经回答了您自己的问题:)像FormClosing和Timer'sTick事件这样的事件都在一个线程上运行。计时器无法“打断”线程并运行勾选事件,您的线程正忙于执行清理工作。在线程完成运行事件处理程序并重新进入消息循环后再次空闲之前,Tick事件不会运行。

    但在这种情况发生之前,表单将自行销毁,并处理其所有控件和组件。这就结束了计时器计时事件运行的任何机会。不需要显式地停止()。

    对于System.Timers.Timer或其他异步组件(如BackgroundWorker),情况并非如此。它是 非常 重要的是在表格关闭前停止这些操作。如果您不这样做,那么您的代码通常会轰炸一个ObjectDisposedException。尤其是System.Timers.Timer是 非常 很难停止,它可以在用户关闭窗体前一微秒调度调用经过的事件处理程序的线程。当这种情况发生的时候。不要使用它。