【问题标题】:Why is a DispatcherTimer Tick event not occurring on time?为什么 DispatcherTimer Tick 事件没有按时发生?
【发布时间】:2011-09-27 09:58:42
【问题描述】:

我想禁用一个按钮-以防止双击:在平板电脑上,您按下一次,它单击了两次,这是我所知道的最简单的 hack-,但我注意到了/debugged 间隔在实践中可能太长了; 50 毫秒 vs > 2 秒。

只有一行启动计时器,一行停止。随机间隔为 50 毫秒或更大。没有 CPU 消耗,我只需在我的 4 核台式电脑上用鼠标单击按钮。

是什么原因?

    DispatcherTimer timerTouchDelay = new DispatcherTimer();

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        //Init
        if (timerTouchDelay.Interval.Milliseconds == 0)
        {
            timerTouchDelay.Tick += new EventHandler(timerTouchDelay_Tick);
            timerTouchDelay.Interval = new TimeSpan(0, 0, 0, 0, 50); //ms

        }


        if(timerTouchDelay.IsEnabled)
            return;

        timerTouchDelay.Start();

        HandleKeyDown();
        base.OnMouseDown(e);
    }

    private void timerTouchDelay_Tick(object sender, EventArgs e)
    {
        timerTouchDelay.Stop();
    }

【问题讨论】:

  • 你不能只在 OnMouseDown 函数中禁用它并在第一个 timerTouchDelay_Tick 上启用它。

标签: c#


【解决方案1】:

要了解为什么会这样,我强烈推荐以下文章:

Comparing the Timer Classes in the .NET Framework Class Library

作为参考,DispatcherTimerSystem.Windows.Forms.Timer 非常相似,作者指出“如果您正在寻找节拍器,那么您来错地方了”。此计时器并非旨在以精确的时间间隔“滴答”。

【讨论】:

  • 我认为我需要替换代码中的所有 DispatcherTimers,在慢速 PC 中,应用程序的行为不同。但这在 50 毫秒和 ~1++ 秒之间是一个巨大的差异......
【解决方案2】:

与其运行计时器,不如只记录最后一次按下按钮的时间。如果超过 50 毫秒,则继续执行该操作,否则直接退出。

DateTime lastMouseDown = DateTime.MinValue;

protected override void OnMouseDown(MouseButtonEventArgs e)
{
    if(DateTime.Now.Subtract(lastMouseDown).TotalMilliseconds < 50)
       return;
    lastMouseDown = DateTime.Now;

    HandleKeyDown();
    base.OnMouseDown(e);
}

【讨论】:

  • 感谢您的想法,它非常有效。 VB6 之类的静态变量现在会很好......
猜你喜欢
  • 1970-01-01
  • 2020-04-15
  • 2017-11-08
  • 2012-11-17
  • 2011-05-18
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多