0

Does anyone know why control would never get to the delegate although it is invoked? It doesn't get there regardless if I'm step-debugging or not.

public void UpdateClock()
{
    //control never gets here 
}

delegate void UpdateClockDelegate();    

private void MT_TimerTick(object source, ElapsedEventArgs e)
{
    if (InvokeRequired) 
    { 
        //control gets here, but does not invoke, apparently
        Invoke(new UpdateClockDelegate(UpdateClock)); 
    }
}

I based this solution according to the explanation in the following link

4
  • 6
    Is your timer enabled? Commented Apr 23, 2013 at 7:56
  • Should be if the debugger gets there. (Tick Event gets fired) Commented Apr 23, 2013 at 7:58
  • Could the UI be blocked? When you call Invoke(), behind the scenes it posts a message to the application's message queue which must be processed by the control's message pump. If the UI is currently blocked, the message won't be processed and the method won't be called. Commented Apr 23, 2013 at 7:58
  • You need to set Timer.Enabled to true (or call Start()) if you want the timer to raise the event. Did you do that? Commented Apr 23, 2013 at 8:03

3 Answers 3

1

Invoke and InvokeRequired are normally used to ensure that a function is executed on the UI-thread. It normally Invokes itself, not another function.

Your code could become like this:

public void UpdateClock()
{
    ...
}

private void MT_TimerTick(object source, ElapsedEventArgs e)
{
    if (InvokeRequired) 
    { 
        Invoke(new Action<object, ElapsedEventArgs>(TimerTick), source, e); 
    }
    else
    {
        UpdateClock();
    }
}

Furthermore, I agree with Scorpi0 to use the System.Windows.Forms.Timer, which will always fire the event on the UI-thread automatically.

Sign up to request clarification or add additional context in comments.

Comments

0

I think you are mixing System.Timers.Timer and System.Windows.Forms.Timer.

  • System.Timers.Timer : the event is called Elapsed, it takes a ElapsedEventArgs
  • System.Windows.Forms.Timer : the event is called Tick, it takes a EventArgs

As I can see, the signature

MT_TimerTick(object source, ElapsedEventArgs e) 

ring an alarm.
It should be either

MT_TimerElapsed(object source, ElapsedEventArgs e)

or

MT_TimerTick(object source, EventArgs e)

Check you are using the good one, and your event are subscribe.

 - For System.Timers.Timer

 MT_Timer.Elapsed += new ElapsedEventHandler(MT_Timer_Elapsed);
 MT_Timer.Start();
 void MT_Timer_Elapsed(object sender, ElapsedEventArgs e) { }

   - For System.Windows.Forms.Timer

MT_Timer.Tick += new EventHandler(MT_Timer_Tick);
MT_Timer.Start();
void MT_Timer_Tick(object sender, EventArgs e) { }

Comments

0

Try this, hope it can help you...

public void UpdateClock()
{
    this.MT_TimerTickCompleted += delegate(object sender, ElapsedEventArgs e)
    {
        //When MT_TimerTick occur, do something
    };
}

delegate void UpdateClockDelegate();    

private void MT_TimerTick(object source, ElapsedEventArgs e)
{
    if (InvokeRequired) 
    { 
        MT_TimerTickNotify(object, e); 
    }
}

public event EventHandler MT_TimerTickCompleted;
private void MT_TimerTickNotify(object sender, ElapsedEventArgs e)
{
    if (MT_TimerTickCompleted != null)
        MT_TimerTickCompleted(sender, e);
}

1 Comment

Thanks everybody for your answers. My current theory on why this doesn't work is as follows: I have Parallel.Invoke going. This makes the threads go into MT_TimerTick, but the main UI thread (to which UpdateClock() belongs to) is halted until parallel.invoke ends. I should replace parallel.invoke with background workers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.