在下面的代码中,是否有可能在myForm_FormClosing之后调用timer_Tick。
如果有机会:在myForm_FormClosing中调用myForm_FormClosing ()以避免timer_Tick在myForm_FormClosing之后被调用,是否就足够了?
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)
{
}
}
}Update:在接受了一些提示(谢谢帮助)之后,我基本上选择了下面的代码来实现我想要的。请不要说在调用timer1_Tick之后还可以调用myForm_FormClosing!这个解决方案只是引入了一个标志(我称之为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;
}
}
}发布于 2012-08-14 17:46:50
是的是可能的。根据医生们 ..。
在窗体关闭之前发生。 当窗体关闭时,它将被释放,释放与该窗体关联的所有资源。
计时器将在FormClosing事件之后才会被释放。下面是一个非常精心设计的示例,说明它是如何发生的。在调用FormClosing之后,您将看到在计时器滴答上命中调试器断点。
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);
}
}
}发布于 2012-08-14 18:20:09
如果使用计时器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
}
[...]
}另一个所以问题有相关信息。
编辑:上面的代码只有在使用System.Timers.Timer而不是System.Windows.Forms.Timer时才有效。
发布于 2012-08-14 17:24:08
我不这么认为,但无论如何最好还是调用timer.stop()。如果您需要它,尽管您应该在program.cs中创建timer对象
https://stackoverflow.com/questions/11957486
复制相似问题