简体   繁体   中英

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM