如何将窗口运行到新任务中并保持其主线程运行

A.D*_*.D. 4 c# wpf multithreading dispatcher

正在开发 WPF / MVVM 应用程序。将 MVC 窗口从主线程显示到新任务并让主线程继续运行其下一条指令而不等待窗口关闭的最佳方法是什么?

我想运行以下命令:

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

window.Show();

... program then continues with business stuff
Run Code Online (Sandbox Code Playgroud)

显然,如果我跑

 window.Show();
Run Code Online (Sandbox Code Playgroud)

窗口立即返回并关闭。

如果我使用

 window.ShowDialog()
Run Code Online (Sandbox Code Playgroud)

线程等待用户关闭窗口,这不是我想要的,因为我需要下一个指令才能继续。

我想我需要将窗口运行到新线程中,但这会带来额外的问题:

 Task.Run(() => window.ShowDialog())); 
Run Code Online (Sandbox Code Playgroud)

这也不起作用,因为窗口被创建为不同的东西。

所以我想我需要使用调度程序才能在新任务中运行 window.ShowDialog :

Task.Run(() => Application.Current.Dispatcher.Invoke(() => window.ShowDialog() ));
Run Code Online (Sandbox Code Playgroud)

但这也行不通。尽管编译器接受它并且在运行时不会抛出异常,但该窗口永远不会打开。如果我以逐步模式进行调试,我可以看到调试器永远不会在新任务中进入匿名状态。

这应该非常简单,但我只是无法解决这个问题。感谢您提前提供的帮助。

Win*_*don 5

Window.Show()不会阻塞线程。它也不会立即返回,直到用户关闭另一个窗口(或者以编程方式关闭它)。所以这可能就是你想要的。

如果您希望主窗口和 MVC 窗口有单独的 UI 线程,您可以在另一个线程中启动新窗口,并为新 UI 线程执行必要的管道操作。

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();
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅@Reed Copsey的这篇博文。