我有一个 System::Windows::Forms::UserControl 的子类,它分配一些必须在析构函数中释放的非托管资源。它通过 WindowsFormsHost 在 WPF 应用程序中使用。如果控件在应用程序中至少显示一次,则将调用它的析构函数。但是,如果创建了控件的实例但从未显示,则只会调用终结器。
为什么会这样?
CLI 类包装器IDisposable
默认实现。如果您不调用您的实例,则不会MyCLIClass::Dispose()
调用析构函数。我不是 WPF 专家,但是当你展示你的控件时,你必须传递一个对处理控件处置的其他类的引用。如果你不这样做,它永远不会被调用。
调用 IDisposable::Dispose() 调用你的 ~destructor。这是一个可选调用,必须由其他代码显式调用。当您将控件添加到容器(如窗体或面板)的控件集合中并且容器得到正确处理时,您将得到它。当用户通过单击关闭按钮关闭窗口时,这通常是自动的。
许多“自动”不起作用的场景。臭名昭著的是当您通过调用 Controls::Remove/At() 或 Controls::Clear() 方法自己删除控件时。当您刚刚使用 gcnew 创建实例但实际上从未通过将其添加到容器控件中使其可见时,它肯定不会是自动的。ControlsCollection 类无法完成它的工作。
可选调用需要由保证调用来支持。当需要释放非托管资源时,您必须始终实现 !finalizer。因此,无论出于何种原因,当使用您的控件的代码跳过可选调用时,它们永远不会被泄露。稍后将调用!finalizer 。