从析构函数中调用BeginInvoke

Jon*_*nek 7 .net c# wpf dispatcher

我在WPF应用程序中有一些代码如下所示:

public class MyTextBox : System.Windows.Controls.TextBox, IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        Dispatcher.BeginInvoke((Action) delegate
        {
            // do work on member variables on the UI thread.
        });
    }

    ~MyTextBox()
    {
        Dispose(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

dispose方法永远不会被显式调用,因此析构函数会调用它.看起来在这种情况下,对象将在BeginInvoke中的委托在UI线程上触发之前被销毁.它似乎工作了.这里发生了什么?这样安全吗?

Yuv*_*kov 4

在这种情况下,在 BeginInvoke 中的委托在 UI 线程上触发之前,对象似乎会被销毁

终结器将工作排队到 UI 消息循环。在 UI 线程上调用实际委托之前,对象可能会完成其终结器方法的运行,但这并不重要,因为无论如何委托都会排队。

这里发生了什么?

您正在将工作从终结器排队到 UI。

这安全吗?

安全是一个广义的术语。我会这样做吗?当然不。从终结器调用 UI 元素的操作看起来和感觉都很奇怪,特别是考虑到这是一个TextBox控件。我建议您充分了解运行终结器可以保证什么,不能保证什么。首先,运行终结器并不意味着对象会立即在内存中被清理。

我还建议阅读@EricLippert 的帖子:为什么你所知道的一切都是错误的第 1 部分第 2 部分