我有一个 WPF 程序,它使用 aCanvas
内的 a Window
,覆盖成为 a Graphics_Canvas
,如下所示:
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()
返回 a Visual
,在其上绘制 a RenderTargetBitmap
,它本身不会保留在该方法之外。
我的问题是为什么这会导致内存使用量变化如此之大?
目前这更像是一个奇怪的麻烦,但我可以预见,如果可用内存一开始就受到更多限制,这可能是一个问题。
任何见解将不胜感激。
* 更新 (21/03/2013) *
通过对 的试验Graphics_Canvas
,似乎以下方法对未释放的内存量产生了相当大的影响:
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
如果我只是返回 anew DrawingVisual()
作为测试,那么在重新绘制结束后,内存几乎可以恢复到原来的位置。
但是,删除这个方法只是意味着Canvas
不会运行,我会得到一个错误。可能是.NET 在幕后某个地方引用了Visual
从这个方法返回的内容,然后没有取消引用它?我该如何排序?(注意:我从未在我的代码中显式调用此方法,它是从其他地方调用的)。