0

I'm trying to show a new window if certain conditions are met, which is checked periodically using a System.Timers.Timer.

I am very new to WPF but from what I've read from my previous question, dispatchtimers use the UI thread and are suitable for UI components, whereas the System.Timers.Timer event runs on a threadpool thread. I had previously accomplished this using my dispatchtimer, but this caused my program to stop responding when trying to exit.

Realizing that the error message: "The calling thread must be STA, because many UI components require this." is probably referring to the fact that I can't open a new window using my System.Timers.Timer, I tried doing the following:

private void timer1_Tick(object sender, EventArgs e)
{
    //... other timer functions
    if(conditions are met)
    {
          ShowNewWindow();
    }

}
private static void ShowNewWindow()
{
    NewWindow nw = new NewWindow();
    nw.Show();
}

This results in the same error message. Do I need to use a different timer type?

Community
  • 1
  • 1
Alex
  • 689
  • 1
  • 8
  • 22
  • 1
    The reason your program froze on close with DispatchTimer likely the fact that you must close every window you `new` even if that window is never shown. The code you did with your DispatchTimer likely newed up a window, never called `.Show()` and never called `.Close()`, this causes that lock up effect. – Scott Chamberlain Mar 05 '15 at 00:24
  • Not so sure about this. I've tested and verified that the program stops responding even when no new window events were fired other than the main window when logging out or closing from task manager. I think that with 4 dispatchtimers running and a lot of database work being done on those timers, not using the main ui thread is probably a good idea anyway. – Alex Mar 05 '15 at 00:33
  • 1
    @AlexB WPF's **Application** class has a property called [**ShutdownMode**](https://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode(v=vs.110).aspx). Have you tried setting this to **OnMainWindowClose**? This will ensure your application exits when the main window closes, regardless of how many other windows in your app are still open. The default value is **OnLastWindowClose** which only exits the app when _all_ windows have been closed. This might explain the behaviour you are seeing. **ShutdownMode** is set in the application XAML file (usually `App.xaml`). – Steven Rands Mar 05 '15 at 09:38
  • Is it ok to have a lot of database functions and other background work on 4 separate dispatchertimers running on the UI thread? – Alex Mar 05 '15 at 18:40
  • @AlexB I'm not sure who your last comment was directed at, but no, it's not really a good idea to do background work on a **DispatcherTimer** as that type of timer will invoke your work on the UI thread. At that point, your "background" work is no longer running in the background, so to speak. – Steven Rands Mar 06 '15 at 10:46
  • @AlexB By the way, did you try the **ShutdownMode** suggestion I made earlier? – Steven Rands Mar 06 '15 at 10:47
  • @StevenRands yes, I did, and it helped quite a bit. Thank you. – Alex Mar 10 '15 at 14:39

0 Answers0