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

C# 关闭WPF应用程序时关闭非托管资源,c#,wpf,mvvm,C#,Wpf,Mvvm,我目前在使用MVVM WPF应用程序时遇到一些问题。在应用程序中,ViewModel使用ResourceDictionary中的DataTemplate作为视图的DataContext进行关联—这样,两个对象都没有对另一个对象的代码内引用。我的ViewModel有一个非托管资源,当我的ViewModel消失时需要释放该资源。(在本例中,我的资源是使用外部DLL的类) 如果我没有实际使用DLL,当我关闭应用程序时,会调用非托管资源的终结器,它会清理DLL(我正在实现IDisposable)。那里一

我目前在使用MVVM WPF应用程序时遇到一些问题。在应用程序中,ViewModel使用ResourceDictionary中的DataTemplate作为视图的DataContext进行关联—这样,两个对象都没有对另一个对象的代码内引用。我的ViewModel有一个非托管资源,当我的ViewModel消失时需要释放该资源。(在本例中,我的资源是使用外部DLL的类)

如果我没有实际使用DLL,当我关闭应用程序时,会调用非托管资源的终结器,它会清理DLL(我正在实现
IDisposable
)。那里一切都好

如果我使用DLL,当我关闭应用程序时,我的资源的终结器不会被调用,进程也不会结束。如果我中断,我可以看到DLL在调用
System.Net.Sockets.Socket.Receive()
时阻塞。我假设现在发生的事情是,我的DLL在某种程度上比我的ViewModel长,所以ViewModel永远不会被最终确定

从我所读到的内容来看,依赖一个最终确定的对象是糟糕的设计——你不能信任GC。那么,如果视图和ViewModel彼此没有引用,那么当我想关闭AppApplication时,我必须在我的资源上调用哪些选项

编辑:这是我参考的关于终结器的文章,需要额外阅读


编辑2:我提出了一个我相当满意的解决方案,所以我想我应该为后代添加它,并伪结束这个问题。在应用程序启动时,我初始化了我的应用程序的主视图和视图模型,因此它是一个同时引用了这两个视图和视图模型的源。我在
View.Closed
上附加了一个EventHandler,它在我的ViewModel上触发一个CleanUp()方法,该方法能够在整个应用程序中传播该逻辑。我维护MVVM,并且可以毫不费力地清理有问题的资源。

不,您完全可以信任GC。您不能相信没有编写启动调用Socket.Receive()的线程的DLL。您必须通过与DLL代码的所有者交谈来解决这个问题。如果你真的自己创建了这个线程,那么就把它的IsBackground属性设置为true。

我试着在一个线程上调用DLL调用,我把IsBackground设置为true,但是我仍然有同样的问题。我希望如果UI调度程序没有其他事情可做,它可以强制另一个停止。+1用于将IsBackground设置为true(如果您拥有该线程)。您可以依靠GC完成对象,但不能依靠GC为您释放对对象的引用。如果您的对象引用了任何其他未分解的对象(事件处理程序是一个大对象),那么GC将不会删除您的对象。本质上,你仍然可以在.NET中存在内存泄漏,并消耗掉你计算机上所有可用的内存,只是没有一个可以逃出你的AppDomain——因此当你的应用程序关闭时,你可以信任GC释放与你的应用程序相关的所有内存。