2017-03-15 58 views
0

有一個複雜的應用程序,我試圖簡化場景。有一個主機.exe(.NET),其中包含許多控件(ActiveX,.NET,WPF)。
一個控件基本上是一個帶有條目的網格(稱爲「list」),當新的選擇發生時,它會向另一個WPF控件(稱爲「DataView」)發送消息。 「DataView」將顯示當前選擇「列表」的詳細信息。
當DataView收到該消息時,它將重新創建它的ViewModel,並分配給它的DataContext,因此重新創建它的View。 它的視圖非常複雜(XAML聲明),完整的控件,模板,還包含幾個圖像(類型:NonDPIImage,從圖像派生,幾個基本的非重要變化,只是將其視爲圖像),它的源代碼是一個轉換器,它創建BitmapImages。WPF查看泄漏 - 隱形,但仍然在後臺呈現

<Image.Source> 
    <MultiBinding Converter="{StaticResource ImageConverter}"> 
     ... 

它工作正常,但我注意到,選擇更改後,「DataView」更新變得越來越慢。
我進行了調試,發現經過多次選擇更改後,所有之前的視圖仍在內存中,並且都在渲染其內容,因此ImageConverter會針對之前的所有視圖調用,因此它變得越來越慢。

我試圖配置文件,這是我看到10 +選擇後。

enter image description here

你看前面的意見仍然在內存(低PRIO的問題),與圖像,而那些仍然被渲染(高研所的問題),使應用程序慢。我不是很熟悉WPF,我在閱讀漏洞之後(大多數情況下不使用DependencyProperty或類似的方法),但是這個控件非常困難,所以我首先要快速解決方法,以防止渲染泄漏的視圖,然後調查內存問題。 (當然兩者都是最好的...)

我試過之前 DataContext分配給新值,將當前View Image.Source設置爲null,所以至少泄漏的Image不會自己渲染,但是導致新的視圖(!)也失去了它的Image.Source,看起來像WPF緩存或共享像一些靜態數據?由於我的第一個prio是停止「隱形渲染」,在此之後,我嘗試在創建新模型之前將一些模型屬性設置爲null(所以它仍會泄漏,但至少不再渲染),因此,所以當Converter收到屬性來創建圖像時,會看到它是空的,並跳過渲染。
但它表現得很奇怪!
對於泄漏的實例,斷點在properties_get代碼中沒有命中,就像WPF緩存了值左右? 這阻止了我繼續這條路。

任何幫助/想法將不勝感激球員。

回答

0

我想我找到了問題:有添加到視圖HwndSource(AddHook())消息掛鉤,但不會被刪除。這保持了整個視圖(見紅色矩形類)的存在。 現在,如果我在UserControl_Unloaded中調用MyHwndSource.RemoveHook(WndProc),View也將是GCd。

0

你可以發佈你的ImageConverter代碼嗎? 這件事是從代碼創建一個圖像,並將其作爲Image對象的源代碼,

可以在它們之間創建強大的鏈接,並在您的場景中發生內存泄漏。 試看看這裏: https://stackoverflow.com/a/21878235/7722174

+0

是的,它是從代碼創建圖像,但它調用'bitmapImage-> Freeze();' - 正如鏈接中所建議的,以防止泄漏。 – Zotyi

+0

是否有任何事件處理程序位於該Image對象之上? 從代碼或視圖(xaml)?任何行爲? – Mishka

+0

我想我發現了這個問題:有一個消息鉤子添加到View HwndSource(AddHook()),但沒有被刪除(例如在UserControl_Unloaded中)。這保持了整個視圖(參見紅色矩形類)。 – Zotyi