2010-08-12 501 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

相關問題