我有一个使用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