9

I'm using 'System.Windows.Forms.Timer' to repeat a task. But when the timer starts, I have to wait for one interval before the task starts. The interval is set to 10 seconds to give the task enough time to do it's thing. But there is an 'awkward silence' waiting for it to start the first time. Is there a way to trigger the Tick event when the timer is enabled? (I am unable to use threading, callbacks or events to get the task repeat)

private int counter;
Timer t = new Timer();

private void InitializeTimer()
{
    counter = 0;
    t.Interval = 750;
    t.Enabled = true;

    t.Tick += new EventHandler(timer1_Tick);
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (counter >= 3)
    {
        t.Enabled = false;                
    }
    else
    {
        //do something here
        counter++;
    }
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
topofsteel
  • 1,267
  • 6
  • 16
  • 25

4 Answers4

13

You can always call your method manually:

private void InitializeTimer()
{
    counter = 0;
    t.Interval = 750;
    t.Enabled = true;
    timer1_Tick(null, null);

    t.Tick += new EventHandler(timer1_Tick);
}
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
JleruOHeP
  • 10,106
  • 3
  • 45
  • 71
  • 3
    Personally - i think calling event handlers like this is smelly : http://en.wikipedia.org/wiki/Code_smell – Richard Friend Aug 22 '12 at 13:05
  • Well, I`m not sure about it. Give it better name - and it is ok. You can create method for this (as in your answer, but you should include all the stuff with checking and incrementing timer thought), but then handler will do nothing except calling this method - is not it worse? – JleruOHeP Aug 22 '12 at 13:14
  • What if another developer changes that method - thinking 'ahh this is just being called when the timer exectues (as the name suggests') he would be expecting the sender argument to at least be a Timer object.. If you want to write professional, readable and maintainable code then you should care about this. http://stackoverflow.com/questions/984270/c-is-calling-an-event-handler-explicitly-really-a-good-thing-to-do – Richard Friend Aug 22 '12 at 13:27
  • Of course, but OP stated that he wanted exactly this behavior :) But overral I do agree with you – JleruOHeP Aug 22 '12 at 13:29
  • 1
    Another issue is that the tick handler is being called directly from the UI thread, and yet according to the question the task can take up to 10 seconds. This will end up locking up the UI for the duration of that task. The timer calls it's event handlers on it's own thread, so the call the timer_Tick(null, null) here should also really be done on a background thread. – Weyland Yutani Sep 02 '13 at 17:01
  • if you dont want to block current thread use this ""System.Threading.Tasks.Task.Factory.StartNew( () => tmr_Elapsed(null, null) ); "" instead of plain "" timer1_Tick(null, null); "" – bh_earth0 Apr 07 '16 at 12:43
8

You could use a System.Threading.Timer.

This has a constructor that takes an initial wait period. Set this to zero and the timer will trigger the callback immediately then every interval you specify thereafter.

Timer stateTimer = new Timer(tcb, autoEvent, 0, 750);
ChrisF
  • 134,786
  • 31
  • 255
  • 325
3

Just create a method then call this from within your timer and also just before you start your timer.

private int counter; 
Timer t = new Timer(); 

private void InitializeTimer() 
{ 
    counter = 0; 
    t.Interval = 750; 

    DoMything();
    t.Tick += new EventHandler(timer1_Tick); 
    t.Enabled = true; 
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    if (counter >= 3) 
    { 
        t.Enabled = false;                 
    } 
    else 
    { 
        //do something here 
        counter++; 
        DoMything();
    } 
} 


private void DoMything()
{
   //Do you stuff here
}
Richard Friend
  • 15,800
  • 1
  • 42
  • 60
1

The simplest way might be to initially set the Interval to something very small, then increase it in the Tick handler, or in a separate handler.

This will ensure the first "tick" occurs in the same manner as subsequent ticks, e.g. on its own thread, rather than in the context of the initialize method.

Rawling
  • 49,248
  • 7
  • 89
  • 127