以下是 Dispatcher 类的注释之一。
如果在后台线程上创建 Dispatcher,请确保在退出线程之前关闭 Dispatcher。
如果在后台线程上创建的调度程序上调用关闭失败,会有什么后果?
我有一个 MFC 应用程序,它在后台线程上创建一个 WPF 窗口。因此,创建了一个调度程序。当我首先关闭 WPF 窗口时,我会在调度程序上显式调用关闭,但是当我关闭 MFC 应用程序时,WPF 窗口也会随之关闭。
调度程序似乎被隐式关闭,或者线程被中止。它是哪一个?
更新:
以下方法创建一个新线程并打开 wpf 窗口。
public void ShowWindow(SomeObject someObject)
{
System.Threading.Thread thread = new System.Threading.Thread((tuple) =>
{
Tuple<Dispatcher, SomeObject> data = tuple as Tuple<Dispatcher, SomeObject>;
Window window = new WPFWindow(data.Item1, data.Item2);
System.Windows.Threading.Dispatcher.Run();
this.tmp = 0;
});
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.IsBackground = true;
thread.Start(new Tuple<Dispatcher, SomeObject>(Dispatcher.CurrentDispatcher, someObject));
}
因此,我在“this.tmp = 0;”语句中打断 当我关闭 MFC 应用程序时它不会受到影响。假设 Dispatcher 没有被关闭,但线程被中止,这是否安全?
如果线程被中止,后果是什么?
更新:
在另一个项目中,我遇到了一个问题,GC 似乎没有完成它的工作。事实证明,它与在未关闭的后台线程上启动的 Dispatcher 有关。每次在后台线程上运行任务时,WPF 应用程序的内存使用量都会不断增加。因此,无论您是否显式创建了 Dispatcher 对象,请务必在后台线程上创建的 Dispatcher 上调用 shutdown。
不在后台线程上创建的 Dispatcher 上调用关闭将导致内存/资源泄漏。调度程序对象挂在资源上。因此,GC 无法清理它们。
为了确保调度程序正确关闭,在我的情况下,我必须从应用程序的 MFC 端生成后台线程,然后让主线程在它完全关闭之前等待它。正如 Hans Passant 所指出的,除非明确告知,否则 MFC 不会等待。