为什么我的 System.Timers.Timer 事件在 C# 中没有触发
本文关键字:System 我的 Timers Timer 事件 为什么 | 更新日期: 2023-09-27 18:20:16
System.Timers.Timer timer = new System.Timers.Timer();
private void button1_Click(object sender, EventArgs e)
{
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Interval = 2000;
timer.Enabled = true;
timer.Start();
}
private void timer_Elapsed(object myobject, System.Timers.ElapsedEventArgs e)
{
Say("Time hit" + DateTime.Now.ToString());
}
我错过了什么?
编辑:
尝试添加:
timer.AutoReset = true;
对于那些好奇的人说方法是:
private void Say(string s)
{
try
{
txtSay.AppendText(s + "'r'n");
}
catch
{
}
}
说方法在那里没有问题。适用于其他所有内容。
我想你没有提到你得到交叉线程异常。尝试像这样更改代码:
Invoke(new Action(()=>Say("Time hit" + DateTime.Now.ToString())));
因为
- 您的定时器未设置同步对象
- 因此,您的事件在另一个线程上触发
- 设置 Text 属性引发跨线程异常
-
然后你不留痕迹地吞下了那个异常
private void Say(string s) { try { txtSay.AppendText(s + "'r'n"); } catch // empty catch-block: the real fundamental problem { } }
因此,Timer 事件确实会触发,但它会产生一个保持隐藏的错误。
简短而实用的解决方案是使用Windows.Timer作为GUI相关的计时器。
这可能不正确,但按照MSDN示例,您不需要调用t.Start((,t.Enable应该启动它。由于通过执行 t.Enabled 和 t.Start 来启动它,因此可能会与 AutoRest 属性发生一些冲突。
我还会通过添加断点或类似的东西来确保 Say 方法正常工作。我不知道在这种情况下你叫什么 AppendText。
一点点猜测工作。
不需要在 Click 方法中设置 EventHandler。例如,在类的构造函数中设置它,它将起作用。
将 Start(( 方法保留在单击函数中:
private void button1_Click(object sender, EventArgs e)
{
timer.Start();
}
正如 Reniuz 所说,您可能会收到异常,因为您正在尝试从不同的线程更新 UI。 Timer
类在单独的线程上运行,以防止它干扰应用程序的响应能力。
这是一个很好的例子,说明为什么try { /* something */ } catch {}
是一个坏主意 - 你通过写这篇文章完全隐藏了自己的错误。 如果您没有编写该代码,您可能已经能够确定您需要从异常消息中在正确的线程上调用 UI 更新。
在 C++/CLI(托管C++ using.NET - 它实际上对 C# 关闭(中,您应该设置对象以通过此计时器进行同步。
它可能看起来像这样: +-
timer->SynchronizingObject = txtSay;
在 C# 中可能:使用 ">."> 而不是 "->">
看到这个技巧