WPF应用程序关闭时关闭非托管资源

时间:2010-08-12 18:02:15

标签: c# wpf mvvm

我目前在使用MVVM WPF应用程序时遇到了一些麻烦。在应用程序中,ViewModel在ResourceDictionary中使用DataTemplate作为View的DataContext关联 - 这样两个对象都没有对另一个对象的in-code引用。我的ViewModel有一个非托管资源,需要在我的ViewModel消失时释放。 (在这种情况下,我的资源是使用外部DLL的类)

如果我实际上没有使用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 个答案:

答案 0 :(得分:1)

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