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

时间:2023-02-15 20:58:21

The following is one of the remarks on Dispatcher class.

下面是Dispatcher类的一个注释。

If you create a Dispatcher on a background thread, be sure to shut down the dispatcher before exiting the thread.

如果在后台线程上创建调度程序,请确保在退出线程之前关闭调度程序。

What are the consequences if one fails to invoke shut down on a dispatcher created on a background thread?

如果在后台线程上创建的分派器没有调用关机,会有什么后果?

I have an MFC application which creates a WPF window on a background thread. Consequently, a dispatcher is created. When I close the WPF window first, I get to explicitly invoke shutdown on the dispatcher, but when I close the MFC application, the WPF window closes along.

我有一个MFC应用程序,它在后台线程上创建WPF窗口。因此,将创建一个分派器。当我首先关闭WPF窗口时,我将在分派器上显式地调用shutdown,但是当我关闭MFC应用程序时,WPF窗口将随之关闭。

It seems the dispatcher is being shut down implicitly, or the thread is being aborted. Which is it?

似乎调度程序正在隐式地关闭,或者线程正在被中止。它是哪一个?

Update:

更新:

The following method creates a new thread and opens the wpf window.

下面的方法创建一个新线程并打开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));
}

So, I put a break along the statement "this.tmp = 0;" and it doesn't get hit when I close the MFC application. Is it safe to assume that the Dispatcher is not being shutdown, but the thread is being aborted?

所以,我在"这个"这句话的后面放了个假。当我关闭MFC应用程序时,它不会被击中。假定Dispatcher没有被关闭,但是线程正在被终止,这是安全的吗?

If the thread is aborted, what are the consequences?

如果线程被中止,会有什么后果?

Update:

更新:

On another project, I ran into a problem where the GC doesn't seem to be doing its job. It turns out, it's related to a Dispatcher started on a background thread that is not being shutdown. The WPF application's memory usage just kept increasing every time a task is ran on background thread. So, be sure to invoke shutdown on Dispatchers created on a background thread whether you created a Dispatcher object explicitly or not.

在另一个项目中,我遇到了一个问题,GC似乎没有完成它的工作。事实证明,它与启动在未被关闭的后台线程上的调度程序有关。每当在后台线程上运行任务时,WPF应用程序的内存使用量就会不断增加。因此,无论是否显式地创建分派器对象,都要确保在后台线程上创建的分派器上调用shutdown。

Not invoking shutdown on Dispatcher created on background thread will cause memory/resource leak. Dispatcher objects hang onto resources. Hence, the GC aren't able to clean them up.

在后台线程上创建的调度程序上不调用关机将导致内存/资源泄漏。分派器对象挂在资源上。因此,GC不能清理它们。

To make sure that a dispatcher is shut down properly, in my case, I have to spawn the background thread from the MFC side of the application then have the main thread wait on it before it completely shuts down. As Hans Passant pointed out, MFC doesn't wait unless it is explicitly told.

为了确保一个dispatcher被正确关闭,在我的例子中,我必须从应用程序的MFC端生成后台线程,然后让主线程在它完全关闭之前等待它。正如汉斯·帕萨特指出的那样,MFC不会等待,除非它被明确告知。

1 个解决方案

#1


0  

If you don't shutdown dispatcher, thread will stuck in message loop and don't exit

如果不关闭调度程序,线程将卡在消息循环中,不退出

#1


0  

If you don't shutdown dispatcher, thread will stuck in message loop and don't exit

如果不关闭调度程序,线程将卡在消息循环中,不退出