public Form controlBox;
public delegate void delegateM(int i);
delegateM dm;
System.Timers.Timer timer;
controlBox = new Form();
timer = new System.Timers.Timer();
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.AutoReset = true;
timer.Interval = 50;
timer.Enabled = true;
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
dm = Move;
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体,引发了多个异常
timer.Enabled = true;
}
catch { }
}
void Move(int top)
{
controlBox.Top = top;
}
上面的代码在触发定时器时移动窗体controlBox,当退出窗体controlBox时,运行下面的代码,关闭timer
timer.Stop();
timer.Close();
执行代码timer.Close();之后,通过调试发现,程序引发了多个异常:“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”引发异常的语句正是代码中注释的那句话。
这说明定时器仍然在工作,不停地在触发Elapsed事件。
我应该怎样关闭timer呢?谢谢
9 个解决方案
#1
哪里调用的这个
timer.Stop();
timer.Close();
timer.Stop();
timer.Close();
#2
是不是不同线程造成的。
下面的来自msdn
在一个线程调用 Stop 方法或将 Enabled 属性设置为 false 的同时,可在另一个线程上运行事件处理方法。这可能导致在计时器停止之后引发 Elapsed 事件。Stop 方法的示例代码演示了一种避免此争用条件的方法。
Timer.Stop 方法
http://msdn.microsoft.com/zh-cn/library/system.timers.timer.stop(v=vs.80)
下面的来自msdn
在一个线程调用 Stop 方法或将 Enabled 属性设置为 false 的同时,可在另一个线程上运行事件处理方法。这可能导致在计时器停止之后引发 Elapsed 事件。Stop 方法的示例代码演示了一种避免此争用条件的方法。
Timer.Stop 方法
http://msdn.microsoft.com/zh-cn/library/system.timers.timer.stop(v=vs.80)
#3
在controlBox上面放置了个button,鼠标点击button时,
先timer.Stop();
timer.Close();
再controlBox.Close();
#4
加个判断试一试
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (this.Textbox1.InvokeRequired)
{
dm = Move;
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体,引发了多个异常
timer.Enabled = true;
}
catch { }
}
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (this.Textbox1.InvokeRequired)
{
dm = Move;
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体,引发了多个异常
timer.Enabled = true;
}
catch { }
}
}
#5
不知道啊
#6
if(i>0)
{
hehe
}
#7
谢谢,我实际写的是if (controlBox.InvokeRequired)这样避免了引发异常。
但是关闭timer的问题还是没有解决啊。。
MSDN大段的叙述,看着头晕,像是机器翻译的。
#8
加了判断后的代码:
if (controlBox.InvokeRequired)
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体
}
catch
{ }
else
controlBox.Top = top;
#9
关闭Timer后,timer_Elapsed会再进很多次,还是只有一两次。只有一两次就没有问题了。可能是线程之间的同步问题。
#1
哪里调用的这个
timer.Stop();
timer.Close();
timer.Stop();
timer.Close();
#2
是不是不同线程造成的。
下面的来自msdn
在一个线程调用 Stop 方法或将 Enabled 属性设置为 false 的同时,可在另一个线程上运行事件处理方法。这可能导致在计时器停止之后引发 Elapsed 事件。Stop 方法的示例代码演示了一种避免此争用条件的方法。
Timer.Stop 方法
http://msdn.microsoft.com/zh-cn/library/system.timers.timer.stop(v=vs.80)
下面的来自msdn
在一个线程调用 Stop 方法或将 Enabled 属性设置为 false 的同时,可在另一个线程上运行事件处理方法。这可能导致在计时器停止之后引发 Elapsed 事件。Stop 方法的示例代码演示了一种避免此争用条件的方法。
Timer.Stop 方法
http://msdn.microsoft.com/zh-cn/library/system.timers.timer.stop(v=vs.80)
#3
在controlBox上面放置了个button,鼠标点击button时,
先timer.Stop();
timer.Close();
再controlBox.Close();
#4
加个判断试一试
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (this.Textbox1.InvokeRequired)
{
dm = Move;
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体,引发了多个异常
timer.Enabled = true;
}
catch { }
}
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (this.Textbox1.InvokeRequired)
{
dm = Move;
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体,引发了多个异常
timer.Enabled = true;
}
catch { }
}
}
#5
不知道啊
#6
if(i>0)
{
hehe
}
#7
谢谢,我实际写的是if (controlBox.InvokeRequired)这样避免了引发异常。
但是关闭timer的问题还是没有解决啊。。
MSDN大段的叙述,看着头晕,像是机器翻译的。
#8
加了判断后的代码:
if (controlBox.InvokeRequired)
try
{
controlBox.Invoke(dm, new object[] { top });//跨线程移动窗体
}
catch
{ }
else
controlBox.Top = top;
#9
关闭Timer后,timer_Elapsed会再进很多次,还是只有一两次。只有一两次就没有问题了。可能是线程之间的同步问题。