【问题标题】:Timer Tick Event and Thread in WinFormsWinForms 中的 Timer Tick 事件和线程
【发布时间】:2012-10-08 07:21:52
【问题描述】:

我有一个名为SendTimer 的计时器,时间间隔为 30 秒。

protected void SendTimer_Tick(object sender, eventArgs e)
{
      SendTimer.Enabled = false;

      TransferMoney();

      System.Threading.Thread.Sleep(15000);

      GenerateTransactions();

      SendTimer.Enabled = true;
}

我希望一个线程同时正确调用滴答事件。不是同时通过 2 个线程。但正如我在我的日志中看到的那样,它似乎是由一个线程调用的,而另一个线程正在运行。任何想法?因为我分别禁用和启用它。

【问题讨论】:

  • 你用的是什么类型的定时器?
  • 那么,您有 2 个线程必须使用该计时器,并且您不希望它们同时运行?那么为什么不在计时器中使用“锁定”呢?
  • tick事件的代码将在Windows.Forms.Timer的GUI线程上执行。你确定你在使用这个计时器吗?

标签: c# winforms multithreading timer thread-safety


【解决方案1】:

Windows 窗体Timer 根据定义是单线程的。它与多线程无关,因为它通过WM_TIMER 消息流逝,被发送到当前的GUI 线程消息队列。

所以,这个:

不能同时被 2 个线程使用

是不正确的,因为即使你有多个线程,WinForms Timer 也与此无关。

【讨论】:

  • 所以你说启用和禁用是不必要的?
  • @Dennis - 不确定这是否正确。 AFAIK,当 GUI 线程进行 GetMessage() 调用并在 Windows 消息队列内部数据中设置事件标志时合成 WM_TIMER“消息”。每个计时器类都有一个标志,它没有计数并且只能设置一次 - 如果它已经设置,则不会发生任何事情。因此,WM_TIMER 消息不可能排队。
  • @MartinJames:你说得对,我的评论有误,我会改正的。
  • @levi:我还没说过。 :) WM_TIMER 的单线程性质仅保证消息处理程序(在您的情况下为 SendTimer_Tick 方法)将在 GUI 线程中调用。但是,如果启用了计时器,并且 WM_TIMER 处理程序执行时间过长(与经过间隔相比),您将在当前处理程序调用返回后立即获得下一个处理程序调用。
  • private void timer1_Tick(object sender, EventArgs e) { MessageBox.Show("TEST"); } 在这种情况下,应该保留一个消息框,直到它被点击,但它显示了很多?..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多