在最新版本的MVVM-light(V3 SP1)中,ViewModel类中的“Dispose()”和“Dispose(bool)”方法都标记为
不再使用此方法,将在以后的版本中删除它。请改用ICleanup.Cleanup()
这是否意味着不能在从GalaSoft.MvvmLight.ViewModelBase派生的所有ViewModel类中实现IDisposable接口(并且必须覆盖清理)?
如果是,使用不能用于视图模型实例......可能我不明白......请澄清......这种清理有什么好处?
感谢。
答案 0 :(得分:29)
这个问题是历史性的。起初我认为强制所有虚拟机都是IDisposable是个好主意。但是,IDisposable有不同的意图:一旦VM被处置,预计(按照惯例)它将尽快被垃圾收集。在与朋友交谈之后,我意识到强制所有虚拟机都是IDisposable是一个错误。这就是我用ICleanup取代IDisposable的原因。 ICleanup的目的是提供一种清理VM的方法(例如将其状态刷新到持久存储,关闭流等......)但不一定要尽快将它们垃圾收集起来。
没有什么能阻止您使VM实现IDisposable。我只是不想在ViewModelBase类中保留这个约束,这就是为什么在V4中删除这个接口的原因。
拥有ICleanup的好处是,您可以在ViewModelLocator.Cleanup()的一次调用中清理所有VM。这是VM开发人员提示虚拟机应该考虑为其虚拟机提供清理方法的暗示。
这有意义吗? 干杯, 劳伦
答案 1 :(得分:2)
我想在这一点上我要求与洛朗有所不同。 IDisposable背后的想法是,对象可能需要进行一些清理,而不是本身与垃圾收集有关。实际上,大多数时候IDisposable都是为了清理非托管资源而实现的,例如文件句柄,同步对象或数据库连接,这些资源不在GC的范围内。此外,仅仅因为基类实现IDisposable并不意味着它必须具有实际的实现。这可以降级为虚拟Dispose(bool disposing)方法,该方法可以被派生类覆盖,以便它们可以执行清理。
正如Budda所暗示的那样,问题在于IDisposable按照惯例是单向操作。一旦处理了一个对象,它就应该在其公共方法上抛出一个ObjectDisposedException。如果您只想清除资源以便重用该对象,那么清理方法就有意义了。但是,我不一定会删除Dispose功能,它有不同的用途。
答案 2 :(得分:2)
“有趣”的小故事:在我的团队中找到程序员并没有取消订阅事件,我'在我们的视图模型层次结构中'清除'IDisposable只是为了改变我对Dispose是否是正确位置的看法。
在某些情况下,由于MEF以及我们创建视图模型的其他一些时髦方式,很难调用Dispose。这让我想知道它是否正确。然后有一个事实,Dispose需要一些照顾(和一个片段)才能做到正确:
DG Update: Dispose, Finalization, and Resource Management
后来,我在一个WP7应用程序(我使用MVVM Light)上做了一些周末工作,并注意到Laurent也改变了主意。
我认为这是正确的决定; IDisposable发送一条消息,“客户”应该尝试将类使用包装在using()中,否则请尽快洗手。
最初,我同意下面帖子中接受的答案,但后来我开始认为JaredPar是对的。
Using IDisposable to unsubscribe events
路