Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timer mystery - Forms.Timer vs. Threading.Timer

Tags:

c#

timer

today I ran into a very interesting problem, which I was luckily able to solve very quickly, however I'd like to know the nature of the problem.

I wrote a control class that manages joystick actions. I wanted to start some action and start the timer on button click and after the timer interval to stop this action.

I have a class(pseudocode) that looks like this :

public class Joystick : UserControl
{
  private Form.Timer timer; //or System.Threading.Timer
  public void Init()
  {
      timer.Tick += new EventHandler(timerCallback)   //Threading.Timer(timerCallback)
      timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite);
  }

   public void ButtonCallback()
   {
      StartSomething();
      timer.Stop();
      timer.Start(); //timer.Change(500, Timeout.Infinite); 
   }   

  public void timerCallback()
  {
     StopSomething();
     timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite);
  }
}

I have two applications, one is really simple (just a form), second one is more complex, however behind this complexity is still an ordinary Form (well DotNetMagicForm) containing this UserControl. Managing code is in both applications absolutely the same, but in the more complex application the timerCallback() was never called. In the simple one everything worked fine. The init was called in both cases (breakpoint). Even if I assign the timerCallback in the ButtonCallback - the timerCallback still wasn't called.

I followed an advice of a colleague of mine and rewrote it by using Threading.Timer instead of Forms.Timer and suddenly it started working in both applications. Neither of us have a clue why it is.

I know my question is quite vague, but what could be the source of this issue?

Thanks

like image 521
Biggles Avatar asked Apr 18 '26 01:04

Biggles


2 Answers

The Threading.Timer does not use a UI message pump to callback the tick. It uses a ThreadPool thread to do so.

The UI timers simply post messages to the form's message pump to solicit the callback. Your background magic form simply wasn't receiving these messages. I'm never sure why though, perhaps because the form is on another thread without a message pump, or inactive forms don't process the pump perhaps.

like image 72
Adam Houldsworth Avatar answered Apr 20 '26 14:04

Adam Houldsworth


Have you had a look at this article comparing the different .NET timer classes

like image 27
IanR Avatar answered Apr 20 '26 14:04

IanR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!