【问题标题】:Timer not running all elapsed event handler计时器未运行所有经过的事件处理程序
【发布时间】:2015-08-17 19:05:42
【问题描述】:

目前正面临这个与计时器有关的问题。我基本上想创建一个将在按下按钮后执行的计时器。这将计数到 5,然后关闭从类创建的窗口。以下是我目前拥有的。

public void startMessageIndicator(string message, bool completed)
{
      messageIndicator.Text = "completed";
      window.Show();
      aTimer = new System.Timers.Timer(5000);
      aTimer.Enabled = true;
      aTimer.Start();
      aTimer.Elapsed += new ElapsedEventHandler(timerElapsed);
      aTimer.AutoReset = true;
}

public void timerElapsed(object sender, ElapsedEventArgs e)
{
      window.Close();
      st.Clear();
      aTimer.Enabled = false;
}

当我编译代码时,我没有遇到任何问题,但是当我进入调试器并使用断点时,它似乎没有运行 window.close() 并且只是卡在该行上。

任何想法我做错了什么

【问题讨论】:

  • 额外的右大括号在做什么?
  • 你的标题表明事件处理程序没有被调用,但你说它卡在window.Close(),那是什么?
  • window是我通过类动态创建的表单
  • 对不起我的错。它进入事件处理程序但似乎没有运行 window.Close();
  • 你不需要启动和启用你的计时器,它们是一样的,只需做一个。如果您希望计时器运行一次并自动停止,则将 AutoReset 设置为 false,无需在 Elapsed 方法中再次禁用它。

标签: c# forms class timer


【解决方案1】:

您应该调用窗口本身的调度程序来更新 UI 线程。

替换

window.close();

window.Invoke((MethodInvoker)delegate
            {
                window.Close();
            });

【讨论】:

  • 这和我的回答一样...window.Invokethis.Invoke 实际上做同样的事情
  • @Fabjan 答案是在您编辑代码之前发布的。您之前的回答没有代表。所以我添加了它并发布了我的答案。
【解决方案2】:

你可以用这个

ExecuteSecure(window.Close);
//OR
ExecuteSecure(() => window.Close());


//---
private void ExecuteSecure(Action action)
{
    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(() => action()));
    }
    else
    {
        action();
    }
}

【讨论】:

    【解决方案3】:

    不要忘记 Timer's Tick 事件处理程序中的方法在单独的线程中执行,而字段 window 是在 UI 线程中创建的。尝试从创建线程之外的其他线程调用方法会导致InvalidOperationException...所以您可以简单地更改您的代码:

    window.Close();
    

    收件人:

    this.Invoke(new Action(() => fr.Close()), null);
    

    现在您在 UI 线程上调用操作,它应该可以按预期工作。

    【讨论】:

    • 错误 1 ​​'practiceProgressBar2.Notifications' 不包含“Invoke”的定义,并且找不到接受“practiceProgressBar2.Notifications”类型的第一个参数的扩展方法“Invoke”(您是否缺少使用指令还是程序集引用?)
    • Invoke(new MethodInvoker(() => window.Close()), null); 在 Windows 窗体应用程序中为我工作。
    • @Patrick well Tick 事件在 UI 线程中执行,但它的处理程序不是。如果您在滴答事件处理程序中添加Thread.Sleep(8000);,您会发现 UI 线程不会冻结 8 秒...
    猜你喜欢
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 2016-09-06
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多