为什么我的 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
            {
            }
        }

说方法在那里没有问题。适用于其他所有内容。

为什么我的 System.Timers.Timer 事件在 C# 中没有触发

我想你没有提到你得到交叉线程异常。尝试像这样更改代码:

Invoke(new Action(()=>Say("Time hit" + DateTime.Now.ToString())));

因为

  1. 您的定时器未设置同步对象
  2. 因此,您的事件在另一个线程上触发
  3. 设置 Text 属性引发跨线程异常
  4. 然后你不留痕迹地吞下了那个异常

    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# 中可能:使用 ">."> 而不是 "->">

看到这个技巧

相关文章: