2010-08-12 260 views
0

我目前在MVVM WPF应用程序中遇到了一些麻烦。在应用程序中,ViewModel在ResourceDictionary中使用DataTemplate作为View的DataContext关联 - 这种方式都不具有对另一个的代码内引用。我的ViewModel有一个非托管资源,当我的ViewModel消失时需要释放它。 (在这种情况下,我的资源是一个使用外部DLL的类)当WPF应用程序关闭时关闭非托管资源

如果我实际上没有使用该DLL,那么在关闭该应用程序时,会调用非托管资源的终结器,这会清理该DLL我正在实施IDisposable)。一切都很好。

如果我使用DLL,当关闭应用程序时,我的资源的终结器不会被调用,并且过程不会结束。如果我中断,我可以看到该DLL在阻止呼叫System.Net.Sockets.Socket.Receive()。我假设发生的事情是,我的DLL超出了我的ViewModel,所以ViewModel永远不会被最终确定。

从我读过的内容来看,依赖于一个正在完成的对象是一个糟糕的设计 - 你不能相信GC。因此,当我想关闭应用程序时,我有什么选择可以在我的资源上调用CleanUp()--鉴于View和ViewModel没有彼此的引用?

编辑:对于一些额外的阅读,这是关于我引用的终结者的blog post

编辑2:我想出了一个解决方案,我很满意,所以我想我会为后人添加它并伪造这个问题。在应用程序启动时,我为我的应用程序初始化主View和ViewModel,所以它是一个对两者都有引用的源。我在View.Closed上附加了一个EventHandler,它在我的ViewModel上触发CleanUp()方法,该方法能够在整个应用程序中传播该逻辑。我维护MVVM并且在没有太多麻烦的情况下清理违规资源。

回答

1

不,你绝对可以信任GC。你不能相信你没有写入的DLL,它们启动了调用Socket.Receive()的线程。您必须通过与DLL代码的所有者交谈来解决此问题。如果您自己实际创建了线程,则将其IsBackground属性设置为true。

+0

我试图在一个线程中调用DLL调用,我将IsBackground设置为true - 但我仍然遇到同样的问题。我希望如果UI调度员没有别的事情可以做,它可以强制另一方停止。 – bsg 2010-08-12 18:40:41

+0

+1将IsBackground设置为true(如果您拥有该线程)。你*可以*依靠GC来完成你的对象,但是你*不能*依靠GC来为你释放对象的引用。如果你的对象引用了任何其他未定义的对象(事件处理程序是一个大对象),那么GC不会删除你的对象。从本质上讲,你仍然可以在.NET中发生内存泄漏,并且消耗掉计算机上所有可用的内存,只是没有任何内存泄漏你的AppDomain - 所以当你的应用程序关闭时,你可以相信GC释放所有与你的相关的内存应用程序。 – Doug 2010-08-12 19:42:36

相关问题