Canvas
a内で aを使用し、オーバーライドして a になる WPF プログラムがあります。これは次のようWindow
になります。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()
返すを追加する必要があります。これ自体は、そのメソッドの外部には保持されません。Visual
RenderTargetBitmap
私の質問は、なぜこれによりメモリ使用量が大きく変化するのですか?
現在のところ、これは興味深い厄介な問題ですが、最初から利用可能なメモリがもっと限られている場合は、問題になる可能性があると予測できます。
どんな洞察も大歓迎です。
* 更新 (2013 年 3 月 21 日) *
で実験したGraphics_Canvas
ところ、次の方法は解放されないメモリの量にかなりの影響を与えるようです。
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
テストとして代わりに aを返すと、new DrawingVisual()
再描画が終了した後、メモリはほとんど元の場所に戻ります。
ただし、このメソッドを削除すると、Canvas
が実行されなくなり、エラーが発生します。舞台裏のどこかで .NET がVisual
このメソッドから返された への参照を作成し、後で参照解除していない可能性がありますか? どうすればこれを並べ替えることができますか? (注: コードでこのメソッドを明示的に呼び出すことはありません。別の場所から呼び出されます)。