4

currently facing this issue with a timer. I basically want to create a timer which will execute after a button press. this will then count to 5 and then close the window which is created from the class. Below is what I have at the moment.

public void startMessageIndicator(string message, bool completed)
{
      messageIndicator.Text = "completed";
      window.Show();
      aTimer = new System.Timers.Timer(5000);
      aTimer.Enabled = true;
      aTimer.Start();
      aTimer.Elapsed += new ElapsedEventHandler(timerElapsed);
      aTimer.AutoReset = true;
}

public void timerElapsed(object sender, ElapsedEventArgs e)
{
      window.Close();
      st.Clear();
      aTimer.Enabled = false;
}

When I compile the code I face no issues however when I go into the debugger and use breakpoints it does not seem to run window.close() and just gets stuck on that line.

Any ideas what I am doing wrong

Khal786
  • 67
  • 8

3 Answers3

2

You should call a dispatcher on the window itself to update UI thread.

Replace

window.close();

with

window.Invoke((MethodInvoker)delegate
            {
                window.Close();
            });
Akansha
  • 933
  • 7
  • 18
  • This is the same as my answer... `window.Invoke` and `this.Invoke` do the same thing practically – Fabjan Aug 17 '15 at 11:04
  • @Fabjan the answer was posted before you edited the code. Your previous answer did not have a delegate. So I have added it and posted my answer. – Akansha Aug 17 '15 at 11:50
1

Don't forget that method in Timer's Tick event handler is executed in a separate thread while field window was created in the UI thread. Attempt to invoke method from other thread than the thread were it was created leads to InvalidOperationException... So you can simply change your code from:

window.Close();

To :

this.Invoke(new Action(() => fr.Close()), null);

Now you invoke action on a UI thread and it should work as expected.

Fabjan
  • 13,506
  • 4
  • 25
  • 52
  • Error 1 'practiceProgressBar2.Notifications' does not contain a definition for 'Invoke' and no extension method 'Invoke' accepting a first argument of type 'practiceProgressBar2.Notifications' could be found (are you missing a using directive or an assembly reference?) – Khal786 Aug 17 '15 at 10:54
  • `Invoke(new MethodInvoker(() => window.Close()), null);` worked for me at Windows Forms Application. – Mitat Koyuncu Aug 17 '15 at 10:54
  • @Patrick well Tick event is executed in UI thread true but it's handler is not. It's became obvious to you if you add `Thread.Sleep(8000);` in tick event handler you'll see that UI thread doesn't freeze for 8 seconds ... – Fabjan Aug 17 '15 at 11:02
1

You can use this

ExecuteSecure(window.Close);
//OR
ExecuteSecure(() => window.Close());


//---
private void ExecuteSecure(Action action)
{
    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(() => action()));
    }
    else
    {
        action();
    }
}
NASSER
  • 5,900
  • 7
  • 38
  • 57