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