2014-01-23 4 views
0


У меня есть кнопка с обработчиками событий мыши.
Когда кнопка нажата (мышь вниз), запускается таймер для имитации других кликов с задержкой. Щелчок запускает преобразование растрового изображения, например. вращение 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; 
} 

Проблема заключается в том, что некоторые преобразования происходят снова после того, как кнопка отпущена, если преобразование займет много времени.
Как я могу подавить остальные?

+0

Возможно, вы можете попробовать другой сценарий. Например, всегда включен таймер. Установите некоторый флаг, когда кнопка мыши нажата во внутренней части, и сбросьте, когда она будет выпущена. Если флаг установлен, 'Timer' будет делать вращение, иначе он не будет. Другое дело - перекрашивать. Скорее, ** измените угол всегда ** и начните перерисовку с помощью 'Invalidate()' (что означает *, пожалуйста, перерисуйте этот элемент управления, как только у вас будет время *) и продолжите угол внутри 'OnPaint', чем то, что вы сделали (это похоже на вы не используете таймер для синхронизации, но полагаетесь на перерисовку, которая похожа, если вы не используете таймер -> зависит от производительности ПК). – Sinatr

+0

Использование OnPaint вместо таймера может быть полезно приспособить перекраску к характеристикам ПК. Я помню эту идею. Спасибо. – user3226852

ответ

0

Похоже, что у вас есть серьезные проблемы с резьбой.

Вы можете проверить, все ли нажата кнопка, установив _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; 
      } 
     } 
    } 
} 
+0

Оператор «lock», кажется, является хорошим решением, нет накопления дополнительных «кликов», и конечная дельта хороша (не увеличивается слишком сильно). Спасибо ! – user3226852

+0

Это помогает понять, что таймер не дождался завершения обработчика 'Tick' до того, как он снова начнет отсчет. Вот почему вам нужно написать собственную логику синхронизации. Это довольно распространенный сценарий, поэтому убедитесь, что вы его не забудете. –

Смежные вопросы