Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run a window into a new task and keep its main thread running

Working on a WPF / MVVM app. What is the best way to display a MVC window from my main thread into a new task and let my main thread keep running its next instructions without waiting for the window to close?

I would like to run the following:

  Window window = new Window();
    View view = new View();
    ViewModel viewModel = new ViewModel();
    window.Content = view;

window.Show();

... program then continues with business stuff

Obviously, if I run

 window.Show();

the window immediately returns and closes.

If I use

 window.ShowDialog()

the thread waits for the window to be closed by the user, which is not what I want as I need the next instructions to proceed.

I suppose that I need to run the window into a new thread but this brings additionnal issues:

 Task.Run(() => window.ShowDialog())); 

This does not work either as window was created into a different stuff.

So I suppose I need to use a dispatcher to be allowed to run window.ShowDialog inside the new Task:

Task.Run(() => Application.Current.Dispatcher.Invoke(() => window.ShowDialog() ));

But this does not work either. Although compiler accepts it and it does not throw exceptions at runtime, the window is never opened. If I debug in step by step mode, I can see that the debugger never enters then anonymous inside the new Task.

This should be very simple but I just do not manage to get this solved. Thx for your kind assistance in advance.

like image 444
A.D. Avatar asked Oct 15 '25 03:10

A.D.


1 Answers

Window.Show() does not block the thread. It also does not immediately return until the user closes the other window (Or you close it programmatically). So that could be what you want.

If you want to have separate UI threads for your Main window and your MVC window, you could start your new Window in another thread and do the necessary plumbing for your new UI thread.

var thread = new Thread(() =>
                        {
                            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));

                            Window window = new Window();
                            View view = new View();
                            ViewModel viewModel = new ViewModel();
                            window.Content = view;

                            // When the window closes, shut down the dispatcher
                            window.Closed += (s, args) =>
                                                 Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

                            window.Show();

                            // Start the Dispatcher Processing
                            Dispatcher.Run();
                        });
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

See this blog post from @Reed Copsey for more details.

like image 163
wingerse Avatar answered Oct 17 '25 17:10

wingerse



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!