正确清理WPF用户控件 [英] Proper cleanup of WPF user controls

查看:110
本文介绍了正确清理WPF用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对WPF相对陌生,与它有关的某些事情对我来说很陌生。首先,与Windows窗体不同,WPF控件层次结构不支持IDisposable。在Windows窗体中,如果用户控件使用了任何托管资源,则通过覆盖每个控件实现的Dispose方法来清除资源非常容易。

I am relatively new to WPF, and some things with it are quite foreign to me. For one, unlike Windows Forms, the WPF control hierarchy does not support IDisposable. In Windows Forms, if a user control used any managed resources, it was very easy to clean up the resources by overriding the Dispose method that every control implemented.

在WPF中,故事并不那么简单。我已经搜索了几个小时,并且遇到了两个基本主题:

In WPF, the story is not that simple. I have searched for this for several hours, and encountered two basic themes:

第一个主题是Microsoft明确声明WPF不会实现IDisposable,因为WPF控件没有不受管理的资源。尽管这可能是正确的,但他们似乎完全没有想到这样一个事实,即对其WPF类层次结构的用户扩展确实可以使用托管资源(通过模型直接或间接使用)。通过不实现IDisposable,Microsoft有效地删除了唯一可以保证清除自定义WPF控件或窗口使用的非托管资源的机制。

The first theme is Microsoft clearly stating that WPF does not implement IDisposable because the WPF controls have no unmanaged resources. While that may be true, they seem to have completely missed the fact that user extensions to their WPF class hierarchy may indeed use managed resources (directly or indirectly through a model). By not implementing IDisposable, Microsoft has effectively removed the only guaranteed mechanism by which unmanaged resources used by a custom WPF control or window can be cleaned up.

第二,我发现了对Dispatcher.ShutdownStarted的引用很少。我尝试使用ShutdownStarted事件,但似乎并非为每个控件都触发。我有一堆WPF UserControl,我已经为ShutdownStarted实现了一个处理程序,但从未被调用。我不确定它是否仅适用于Windows或WPF App类。但是,它不能正确触发,并且每次应用程序关闭时,我都会泄漏打开的PerformanceCounter对象。

Second, I found a few references to Dispatcher.ShutdownStarted. I have tried to use the ShutdownStarted event, but it does not seem to fire for every control. I have a bunch of WPF UserControl's that I have implemented a handler for ShutdownStarted, and it never gets called. I am not sure if it only works for Windows, or perhaps the WPF App class. However it is not properly firing, and I am leaking open PerformanceCounter objects every time the app closes.

是否有比Dispatcher.ShutdownStarted事件更好的替代方式来清除非托管资源?有实现IDisposable的技巧,以便调用Dispose吗?如果可能的话,我宁愿避免使用终结器。

Is there a better alternative to cleaning up unmanaged resources than the Dispatcher.ShutdownStarted event? Is there some trick to implementing IDisposable such that Dispose will be called? I would much prefer to avoid using a finalizer if at all possible.

推荐答案

实际上,Dispatcher.ShutdownStarted确实是WPF提供的唯一机制,用于在UserControls中处置资源。 (请参阅我之前问过的非常类似问题)。

I'm afraid that Dispatcher.ShutdownStarted really does seem to be the only mechanism WPF provides for disposing of resources in UserControls. (See a very similar question I asked a while ago).

解决该问题的另一种方法是将所有可使用的资源(如果可能)移出代码,移入单独的类(例如,使用MVVM模式)。然后在更高级别上,您可以处理主窗口关闭并通过Messenger类通知所有ViewModel。

Another way to approach the problem is to move all of your disposable resources (if at all possible) out of the code behind and into separate classes (such as the ViewModel when using the MVVM pattern). Then at a higher level you could handle your main window closing and notify all the ViewModels via a Messenger class.

我很惊讶您没有收到Dispatcher.ShutdownStarted事件。您的UserControl当时是否已连接到顶层窗口?

I am surprised you don't get the Dispatcher.ShutdownStarted event. Are your UserControls attached to the top-level window at the time?

这篇关于正确清理WPF用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆