22

在最新版本的 MVVM-light (V3 SP1) 中,ViewModel 类中的“Dispose()”和“Dispose(bool)”方法都被标记了

不再使用此方法,它将在以后的版本中删除。改用 ICleanup.Cleanup()

这是否意味着不能在派生自 GalaSoft.MvvmLight.ViewModelBase 的所有 ViewModel 类中实现 IDisposable 接口(并且必须覆盖清理)?

如果是,则 using 不能用于视图模型实例...可能我不明白某些东西...请澄清...这种清理有什么好处?

谢谢。

4

3 回答 3

30

这个问题是历史性的。起初我认为强制所有虚拟机为 IDisposable 是个好主意。但是,IDisposable 有一个不同的意图:一旦 VM 被释放,预计(按照惯例)它将尽快被垃圾收集。与朋友交谈后,我意识到强制所有 VM 为 IDisposable 是错误的。这就是我用 ICleanup 替换 IDisposable 的原因。ICleanup 的目的是提供一种清理 VM 的方法(例如,将它们的状态刷新到持久存储、关闭流等......),但不一定以尽快将它们作为垃圾收集的方式。

没有什么能阻止你让你的虚拟机实现 IDisposable。我只是不想在 ViewModelBase 类中保留这个约束,这就是为什么这个接口将在 V4 中删除。

拥有 ICleanup 的好处是您可以在一次调用 ViewModelLocator.Cleanup() 中清理所有 VM。这是对 VM 开发人员的一个提示,即 VM 应该考虑为其 VM 提供清理方法。

那有意义吗?干杯,劳伦特

于 2010-06-04T09:17:52.503 回答
3

“有趣”的小故事:发现我团队中的程序员并没有取消订阅事件,我在视图模型层次结构中“清洗”了 IDisposable,只是为了改变我对 Dispose 是否是正确位置的想法。

在某些情况下,由于 MEF 和我们创建视图模型的其他一些时髦方式,很难调用 Dispose。这让我怀疑它是否正确。然后是 Dispose 需要一些小心(和一个片段)才能正确处理的事实:

DG 更新:处置、最终确定和资源管理

后来,我在一个 WP7 应用程序(我使用 MVVM Light)上做了一些周末工作,并注意到 Laurent 也改变了主意。

我认为这是正确的决定;IDisposable 发送一条消息,“客户”应该尝试将类使用情况包装在 using() 中,或者尽快洗手。

最初,我同意下面线程中接受的答案,但后来我开始认为 JaredPar 是对的。

使用 IDisposable 取消订阅事件

卢克

于 2011-06-20T09:56:47.557 回答
2

在这一点上,我想我与 Laurent 有所不同。IDisposable 背后的想法是,对象可能需要进行一些清理,并且本身与垃圾收集没有任何关系。事实上,大多数时候 IDisposable 是为了清理非托管资源而实现的,例如文件句柄、同步对象或数据库连接,这些都不在 GC 的权限范围内。此外,仅仅因为基类实现了 IDisposable 并不意味着它必须有一个实际的实现。这可以归结为可以被派生类覆盖的虚拟 Dispose(bool disposing) 方法,以便它们可以执行清理。

正如 Budda 所暗示的那样,问题在于 IDisposable 按照惯例是一种单向操作。一旦一个对象被释放,它应该在它的公共方法上抛出一个 ObjectDisposedException。如果您只想清除资源以便重用对象,那么 Cleanup 方法是有意义的。但是,我不一定会删除用于不同目的的 Dispose 功能。

于 2011-03-14T15:26:57.363 回答