FormClosing后的计时器滴答?

在下面的代码中myForm_FormClosing之后是否有可能调用timer_Tick。

如果有机会:在myForm_FormClosing中调用timer.Stop()是否足以避免在myForm_FormClosing之后调用timer_Tick?

using System; using System.Windows.Forms; using System.ComponentModel; namespace Test { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MyForm()); } } class MyForm : Form { private IContainer components; private Timer timer; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } public MyForm() { components = new Container(); timer = new Timer(components); timer.Interval = 50; timer.Tick += timer_Tick; timer.Enabled = true; FormClosing += myForm_FormClosing; } private void timer_Tick(object sender, EventArgs e) { } private void myForm_FormClosing(object sender, FormClosingEventArgs e) { } } } 

更新 :收到一些提示后(感谢您的帮助)我基本上选择了以下代码来实现我想要的。 请注意,调用myForm_FormClosing后仍然可以调用timer1_Tick! 这个解决方案只引入了一个标志(我称之为doWork),它在调用myForm_FormClosing之后停止timer1_Tick中的代码。

 using System; using System.Windows.Forms; using System.ComponentModel; namespace Test { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MyForm()); } } class MyForm : Form { private IContainer components; private Timer timer; private bool doWork = true; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } public MyForm() { components = new Container(); timer = new Timer(components); timer.Interval = 50; timer.Tick += timer_Tick; timer.Enabled = true; FormClosing += myForm_FormClosing; } private void timer_Tick(object sender, EventArgs e) { if (doWork) { //do the work } } private void myForm_FormClosing(object sender, FormClosingEventArgs e) { doWork = false; } } } 

对的,这是可能的。 根据文件 ……

在窗体关闭之前发生。

当表单关闭时,它会被释放,释放与表单相关的所有资源。

在FormClosing事件之后,计时器才会被释放。 这是一个非常人为的例子,说明它是如何发生的。 在调用FormClosing之后,您将看到在Timer滴答声中点击调试器断点。

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.Threading.Tasks; using System.Threading; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private System.Windows.Forms.Timer _time = new System.Windows.Forms.Timer(); private Task _t1 = null; private Task _t2 = null; private bool _closingFlag = false; public Form1() { InitializeComponent(); _time.Interval = 50; _time.Tick += (s, e) => { textBox1.Text = DateTime.Now.ToString(); if (_closingFlag) Debugger.Break(); }; _time.Start(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { _closingFlag = true; _t1 = Task.Factory.StartNew(() => { Thread.Sleep(1000); }); _t2 = Task.Factory.StartNew(() => { Thread.Sleep(1000); }); Task.WaitAll(_t1, _t2); } } } 

如果您使用计时器System.Windows.Forms.Timer ,UI线程必须处于空闲状态才能处理来自计时器的勾号,因此根据我的理解,这是不可能的。

如果您使用具有自己的线程的计时器,可能会发生,作为System.Timers.Timer 。 在这种情况下,我们可以通过实现以下内容来避免您提到的内容:

 class MyForm : Form { private System.Timers.Timer timer; private Object justForLocking = new Object(); private Boolean safeToProceed = true; [...] public MyForm() { components = new Container(); timer = new System.Timers.Timer(); timer.Interval = 50; timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.Start(); FormClosing += myForm_FormClosing; } void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // In case that this code is being executed after // the method myForm_FormClosing has adquired the // exclusive lock over our dummy resource, // the timer thread will wait until the resource if released. // Once is released, our control flag will be set to false // and the timer should just return and never execute again. lock(justForLocking) { if (safeToProceed) { // Do whatever you want to do at this point } } } private void myForm_FormClosing(object sender, FormClosingEventArgs e) { lock(justForLocking) { safeToProceed = false; } timer.Stop(); // Do something else } [...] } 

这个其他SO问题有相关信息。

编辑:上面的代码只有在使用System.Timers.Timer而不是System.Windows.Forms.Timer时才有效

我不相信,但无论如何最好调用timer.stop()。 如果你需要它,虽然你应该在program.cs中创建计时器对象