以下是对Dispatcher类的评论之一。
If you create a Dispatcher on a background thread, be sure to shut down the dispatcher before exiting the thread.
如果未能对在后台线程上创建的调度程序调用关闭,会产生什么后果?
我有一个 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 调用关闭。
不在后台线程上创建的 Dispatcher 上调用关闭将导致内存/资源泄漏。调度程序对象卡在资源上。因此,GC 无法清理它们。
为了确保调度程序正确关闭,在我的例子中,我必须从应用程序的 MFC 端生成后台线程,然后让主线程在它完全关闭之前等待它。正如 Hans Passant 指出的那样,除非明确告知,否则 MFC 不会等待。
最佳答案
如果不关闭dispatcher,线程会卡在消息循环中不退出
关于c# - 当在后台线程上创建的 Dispatcher 没有关闭时会发生什么?如何确保调度程序正确关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18642444/