0

I have 2 windows in my project.

One is a "loading" window that I am hoping to display on startup, while the other window loads.

The other is the main window, that runs several queries, and therefore takes a little while to load.

Currently, I have a thread that shows the startup window, then loads the main window with a second thread.

However, once the main window has finally loaded, I want the startup window to be hidden, but I'm not sure how to do that, as it is part of another thread.

Putting both windows in the same thread causes the startup window to lag a lot, due to the main window loading in the same thread.

Any suggestions?

private void Application_Startup(object sender, StartupEventArgs e)
{
    Thread MainWindow_Show = new Thread(new ThreadStart(() =>
    {
        MainWindow MainWindowObj = new MainWindow();
        MainWindowObj.Show();

        System.Windows.Threading.Dispatcher.Run();
    }));
    MainWindow_Show.SetApartmentState(ApartmentState.STA);
    MainWindow_Show.IsBackground = true;

    Thread StartupWindow_Show = new Thread(new ThreadStart(() =>
    {
        Startup StartupWindow = new Startup();
        StartupWindow.Show();
        MainWindow_Show.Start();

        System.Windows.Threading.Dispatcher.Run();
    }));
    StartupWindow_Show.SetApartmentState(ApartmentState.STA);
    StartupWindow_Show.IsBackground = true;
    StartupWindow_Show.Start();
}
Uwe Keim
  • 38,279
  • 56
  • 171
  • 280
mouldycurryness
  • 85
  • 1
  • 11
  • 1
    In my experience, it is a severe error if you create a window from a thread other than the main UI thread. At least in WinForms, I guess this is true in WPF, too. – Uwe Keim Aug 30 '18 at 13:43
  • 4
    It's not necessary to put window creation, particularly splash screens into different threads. Just show them normally. Any computationally-long operations should be performed in another thread. That'll stop your windows from blocking – MickyD Aug 30 '18 at 13:45
  • @UweKeim generally true but it is reasonably safe with multiple STA threads which is what the OP is doing. Though, like I said, better that the OP put the work into a worker thread and just show windows normally – MickyD Aug 30 '18 at 13:46
  • Please do not use Threads in WPF. You should use async and await since it is automatically handled in which thread the code is executed. Also you should put your loading logic from MainWindow constructor into a async Task initialize method. – horotab Aug 30 '18 at 13:49
  • You don't need 2 threads, only splash window needs another thread to make it responsive if UI thread of main window is busy (e.g. by loading resources). To *access* it you have to invoke using its dispatcher. Search for "wpf splash thread", there are plenty of implementations or simply make own ;) Btw, `Dispatcher.Run()` is not needed, rather use `ShowDialog()`, other thing is what maybe you don't correctly implement startup method, you know, App.xaml by default also try to create window by using `StartupUri`? I found it better to implement own `Main()` method rather than using `App` events. – Sinatr Aug 30 '18 at 14:08
  • See [this trick](https://stackoverflow.com/a/26890426/1997232). – Sinatr Aug 30 '18 at 14:10
  • 1
    @horotab Even if you're using `async` and `await` to write asynchronous operations more easily, you still need to explicitly indicate whenever you want a thread to be created or a background thread used. Nothing about `await` inherently involves multiple threads. – Servy Aug 30 '18 at 14:11
  • @Servy as far as I know tasks are handled by the TaskPool when using async and await, so if you use Task.Run it might/should use another thread if the taskpool is using many. – horotab Aug 30 '18 at 14:36
  • @horotab No, `Task` may or may not use a thread. A `Task` is a higher-level construct not necessarily 1:1 associated with threads. Only compute tasks (typically created by `Task.Run`) use threads and they _do_ come from the thread pool. I/O tasks don't use a thread at all. https://blog.stephencleary.com/2013/11/there-is-no-thread.html – MickyD Aug 30 '18 at 14:46
  • @horotab Tasks are handled by whatever the method that created them defined them to do. You can create a new task that will create a new thread to do some work, you can create a new task to use a thread pool thread to do some work, you can create a task that doesn't use any new threads to do its work, possibly by having the work done via IO operations. Regardless of what the task does, `await` isn't going to know or care how it actually does its work. – Servy Aug 30 '18 at 15:06

0 Answers0