我有一個使用Canvas
一個Window
內的WPF程序,過度纏身,成爲Graphics_Canvas
,它看起來像這樣:爲什麼連續移除和重新添加DrawingVisual會導致內存使用量不斷增加?
class Graphics_Canvas : Canvas
{
private List<DrawingVisual> visuals = new List<DrawingVisual>();
protected override int VisualChildrenCount
{
get { return visuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
public void AddVisual(DrawingVisual visual)
{
visuals.Add(visual);
base.AddVisualChild(visual);
base.AddLogicalChild(visual);
}
public bool ContainsVisual(DrawingVisual visual)
{
return visuals.Contains(visual);
}
public bool HasVisuals
{
get { return visuals.Count > 0; }
}
public void RemoveAllVisuals()
{
for (int i = 0; i < visuals.Count; i++)
{
base.RemoveVisualChild(visuals[i]);
base.RemoveLogicalChild(visuals[i]);
}
visuals.Clear();
}
public void RemoveLastVisual()
{
if (visuals.Count > 0)
{
int index = visuals.Count - 1;
base.RemoveVisualChild(visuals[index]);
base.RemoveLogicalChild(visuals[index]);
visuals.Remove(visuals[index]);
}
}
public void RemoveVisual(DrawingVisual visual)
{
base.RemoveVisualChild(visual);
base.RemoveLogicalChild(visual);
visuals.Remove(visual);
}
}
(我沒有得到從某處在線,但我不記得在哪裏)
無論如何,該程序允許用戶通過拖動中間的鼠標來平移顯示在Graphics_Canvas
上的圖形,並且這將持續(只要它們保持平移)觸發像這樣的東西:
//get the data visual:
DrawingVisual tempVisual = GetDataDrawingVisual();
//first clear the current display data:
myCanvas.RemoveVisual(dataVisual);
//get the data visual:
dataVisual = tempVisual;
myCanvas.AddVisual(dataVisual);
所以我不斷刪除,然後重新添加dataVisual
。
當我看到內存使用時,我注意到,平移會導致內存使用增加,而當它再次下降時,它不會一直保持原來的狀態。當顯示屏上完全沒有顯示時,這一點更加明顯,並且內存使用不斷地重新添加任何東西都可能會增加到幾百MB,而在平移停止時主要再次下降。
有關信息,我應該補充說明GetDataDrawingVisual()
返回一個Visual
,其上繪製了一個RenderTargetBitmap
,它本身不保留在該方法之外。
我的問題是爲什麼這會導致內存使用變化如此之多?
目前這更多的是一個奇怪的麻煩,但我可以預見,如果可用內存更有限,可能是一個問題。
任何見解將不勝感激。
* UPDATE(21/03/2013)*
從與Graphics_Canvas
試驗,看來下面的方法使多少內存公平的影響尚未發佈:
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
如果我只是將new DrawingVisual()
作爲測試返回,則內存回到幾乎在重新繪製結束後的位置。
但是,刪除此方法只是意味着Canvas
將不會運行,並且會出現錯誤。難道是在幕後.NET的某個地方引用了從這個方法返回的Visual
,然後沒有去引用它?我怎麼能解決這個問題? (注意:我從來沒有明確地在我的代碼中調用這個方法,它是從其他地方調用的)。
在你展示的代碼,視覺您刪除(dataVisual),可能不一樣的,你要添加的一個。你能顯示getDataDrawingVisual代碼嗎? – GameAlchemist 2013-03-20 12:23:08
@VincentPiel真的,它不會總是一樣的,因爲我會改變畫布上的圖形。但是對於上面的例子,我始終生成一個完全空白的圖像,這是因爲Visual的內容沒有任何變化,這讓我覺得在某個地方存在問題。該方法的代碼擴展爲子例程的加載,因此非常冗長,完成的操作取決於用戶設置和加載到程序中的文件數量,因此添加它可能不容易或特別有用。 – Greg 2013-03-20 12:29:22
如果你正在創建一個新的Canvas對象,爲什麼你會期望內存使用不增加? – 2013-03-20 12:38:25