【问题标题】:How to stop remaining actions on timer stop?如何停止计时器停止的剩余动作?
【发布时间】:2014-01-23 18:23:00
【问题描述】:


我有一个带有鼠标单击事件处理程序的按钮。
当按下按钮(鼠标按下)时,会启动一个计时器以延迟模拟其他点击。单击运行位图转换,例如每次旋转0.5。
当释放按钮(鼠标向上)时,计时器停止。
Button类中的代码:

private void TreatMouseDown(object sender, MouseEventArgs e) {
    // Following clicks
    _repeteTimer.Tick += (senderTick, eTick) => {
        _repeteTimer.Stop();
        PerformClick();
        _repeteTimer.Interval = _nextDelay;
        _repeteTimer.Start();
    };
    // First click  
    PerformClick();
    _repeteTimer.Interval = _firstDelay;
    _repeteTimer.Start();
}

private void TreatMouseUp(object sender, MouseEventArgs e) {
    _repeteTimer.Stop();
}

窗口中的代码:

btnRotation1.Click += (sender, e) => PHOTO_Treat(1);

private void PHOTO_Treat(int delta) {
    if (!_inProgress) {
        _photoRotation += delta * 0.5F;
        PHOTO_Show();
    }
}

private void PHOTO_Show(){
    if (_inProgress) return;
_inProgress= true;

    // Make image treatments ...

    _inProgress = false;
}

问题是释放按钮后会再次发生几次转换,如果转换需要很长时间。
我怎样才能抑制剩余?

【问题讨论】:

  • 也许你可以尝试一些其他的场景。例如,让Timer 始终打开。在内部按下鼠标按钮时设置一些标志,并在释放时重置。如果设置了标志,Timer 将进行轮换,否则不会。另一件事是重绘。而是始终更改角度并使用Invalidate() 开始重新绘制(这意味着请尽快重新绘制此控件)并在OnPaint 内继续角度,而不是你做了什么(就像你没有使用定时器来同步旋转,而是依赖重绘,这就像你不使用定时器 -> 取决于电脑性能)。
  • 使用 OnPaint 代替计时器对于使重绘适应 PC 性能很有用。我牢记这个想法。谢谢。

标签: c# timer


【解决方案1】:

听起来你有一些严重的线程问题。

您可以通过检查_repeteTimer.Enabled来检查按钮是否仍然按下。

另外,添加一个锁。即使只是为了安全。

private readonly object SyncRoot = new object();

private void PHOTO_Show()
{
    if (!_inProgress)
    {
        // race for a lock
        lock (SyncRoot)
        {
            // check button state
            if (!_repeteTimer.Enabled)
            {
                // button was released
                return;
            }
            // else
            try
            {
                _inProgress = true;
                MakeImageTreatments();
            }
            finally 
            {
                _inProgress = false;
            }
        }
    }
}

【讨论】:

  • “锁定”语句似乎是一个很好的解决方案,没有额外的“点击”积累,最终的增量很好(没有增加太多)。谢谢!
  • 它有助于理解计时器不会等待Tick 处理程序完成,然后再开始计数。这就是为什么您需要编写自己的同步逻辑。这是一个很常见的情况,所以请确保不要忘记它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 2014-08-24
相关资源
最近更新 更多