我有一个WPF应用程序,在特定模式下每隔0.5秒向UI显示一个文本字符串。我注意到,当发生这种情况时,内存使用量会缓慢而稳定地增加,而这种情况从未发布,如果我让它运行得足够长,它将耗尽内存并崩溃。
执行绘图的代码如下:
public void DrawDisplay( DrawingContext dc, Size size )
{
...
// Draw Text
var fontSize = 46.0;
FormattedText ft = new FormattedText(
message,
CultureInfo.GetCultureInfo( "en-us" ),
FlowDirection.LeftToRight,
new Typeface( "Franklin Book" ),
fontSize,
Brushes.Black );
ft.MaxTextWidth = size.Width - 2;
ft.TextAlignment = TextAlignment.Center;
// don't draw outside of box
ft.MaxTextHeight = size.Height;
// Center
var height = ( size.Height - ft.Height ) / 2;
dc.DrawText( ft, new Point( 0, height ) );
...
}
文本在画布上绘制,其中包含以下代码部分:
DrawingVisual dv = new DrawingVisual();
var size = new Size( canvas.Width, canvas.Height );
using( DrawingContext dc = dv.RenderOpen() )
{
// draw a transparent rect so the text doesn't stretch (fixes size)
dc.DrawRectangle( Brushes.Transparent, null, new Rect( 0, 0, size.Width, size.Height ) );
RadioInterface.DrawDisplay( dc, size );
}
canvas.Background = new VisualBrush( dv );
我能够通过仅注释“dc.DrawText(...”行来“修复”此内存泄漏。这样做,应用程序的内存使用情况完全不变。除此之外,我不确定是什么尝试。我尝试搜索与DrawText相关的内存泄漏,但没有找到任何结果,我的函数中使用的代码几乎与用于DrawText的MSDN站点上的示例相同。
有没有人看过这个或看到我做错了什么?
答案 0 :(得分:2)
因此,经过一些阅读和重新阅读后,我注意到此博客文章中的以下评论:https://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx?Redirected=true
“这只是版本3.5 SP1中出现的WPF泄漏。当在软件渲染模式下在Viewport3D中使用VisualBrush,WriteableBitmap或某些其他类时会发生这种情况。”
我正在使用Viewport,而不是Viewport3D,但我正在使用软件渲染,如果我按照帖子中的建议将VisualBrush更改为SolidColorBrush来测试泄漏,它就会消失。此外,从DrawingVisual转换为DrawingGroup也可以修复泄漏。
将第二个代码块更改为以下内容修复了泄漏:
DrawingVisual dg = new DrawingGroup();
var size = new Size( canvas.Width, canvas.Height );
using( DrawingContext dc = dg.Open() )
{
// draw a transparent rect so the text doesn't stretch (fixes size)
dc.DrawRectangle( Brushes.Transparent, null, new Rect( 0, 0, size.Width, size.Height ) );
RadioInterface.DrawDisplay( dc, size );
}
canvas.Background = new DrawingBrush( dg );
我也尝试过使用DrawingVisual类对象并反复重复使用它,而不是每次绘制时都创建一个新对象,这也修复了泄漏。
编辑:我使用DrawingVisual的原因是它与我尝试的替代品(包括DrawingGroup)相比产生了最低的CPU使用率。差异并不大,但一致。