jri*_*sta 21 wpf user-controls dispose finalizer
我对WPF比较陌生,有些东西对我来说很陌生.首先,与Windows窗体不同,WPF控件层次结构不支持IDisposable.在Windows窗体中,如果用户控件使用任何托管资源,则通过覆盖每个控件实现的Dispose方法来清理资源非常容易.
在WPF中,故事并不那么简单.我搜索了几个小时,遇到了两个基本主题:
第一个主题是微软明确指出WPF没有实现IDisposable,因为WPF控件没有非托管资源.虽然这可能是真的,但他们似乎完全错过了WPF类层次结构的用户扩展可能确实使用托管资源(直接或通过模型间接)的事实.通过不实现IDisposable,Microsoft已经有效地删除了唯一保证机制,通过该机制可以清除自定义WPF控件或窗口使用的非托管资源.
其次,我发现了一些对Dispatcher.ShutdownStarted的引用.我曾尝试使用ShutdownStarted事件,但似乎没有为每个控件触发.我有一堆WPF UserControl,我已经为ShutdownStarted实现了一个处理程序,它永远不会被调用.我不确定它是否只适用于Windows,或者WPF App类.但是它没有正确触发,每次应用程序关闭时我都会泄漏打开的PerformanceCounter对象.
清理非托管资源是否有比Dispatcher.ShutdownStarted事件更好的替代方案?是否有一些技巧来实现IDisposable,以便调用Dispose?如果可能的话,我更愿意避免使用终结器.
Mar*_*ath 12
我担心Dispatcher.ShutdownStarted似乎确实是WPF为在UserControls中处理资源提供的唯一机制.(看到我刚才问过的一个非常类似的问题).
解决这个问题的另一种方法是将所有可支配资源(如果可能的话)移出后面的代码并进入单独的类(例如使用MVVM模式时的ViewModel).然后在更高级别,您可以处理主窗口关闭并通过Messenger类通知所有ViewModel.
我很惊讶你没有得到Dispatcher.ShutdownStarted事件.您的UserControl当时是否附加到顶级窗口?
小智 10
IDisposable接口在WPF下几乎没有任何意义,因为该机制与Winforms不同.在WPF中,您必须牢记视觉和逻辑树:这是基础.
因此,任何视觉对象通常都是其他对象的孩子.WPF构建机制的基础是分层附加可视对象,然后在它们无用时分离和销毁.
我认为您可以检查OnVisualParentChanged暴露的方法,因为UIElement:在附加可视对象和分离时调用此方法.这可能是处理非托管对象(套接字,文件等)的正确位置.
我也在寻找这个,在测试了不同的选项后,我实施了venezia的解决方案
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
if (oldParent != null)
{
MyOwnDisposeMethod(); //Release all resources here
}
base.OnVisualParentChanged(oldParent);
}
Run Code Online (Sandbox Code Playgroud)
我意识到当父调用Children.Clear()Method并且已经将项添加到Children时,DependencyObject有一个值.但是当父项添加了一个item(Children.Add(CustomControl))并且子项为空时,DependencyObject为null.
| 归档时间: |
|
| 查看次数: |
22222 次 |
| 最近记录: |