c# - 当在后台线程上创建的 Dispatcher 没有关闭时会发生什么?如何确保调度程序正确关闭?

标签 c# c++ wpf multithreading mfc

以下是对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/

相关文章:

c# - WaitForExit 实际上是在等待外部程序完成吗?

c# - '/' 应用程序中的服务器错误

c++ - 我如何在我的矩阵类中获得此功能?

wpf - 从后台线程更新 DataContext

c# 获取迭代器在字典中的位置

c++ - 调整 OpenGL 窗口的大小会导致它分崩离析

python - PythonQt 被弃用了吗?

c# - 以编程方式在加载的松散 xaml 文件中的控件上设置文本

c# - 命令绑定(bind)到中继命令不起作用

c# - IEnumerable 是否需要使用 foreach 循环?