WPF使用字体时TextBlock存在内存泄漏问题

16

我正在使用Windows 7上的.NET 4.5,并可能遇到内存泄漏问题。
我有一个TextBlock(不是TextBox - 这不是撤消问题),它每秒更改其值(CPU使用率,时间等)。
使用.NET内存分析器(以及简单地观察任务管理器),我注意到内存不断增长。 更准确地说,我看到越来越多的UnmanagedMemoryStream实例(我尝试了GC.Collect(),但显然没有任何作用)。

经过一些测试,我发现只有当我将TextBlock字体设置为资源字体时,这个问题才会出现:

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="Control.Foreground" Value="#CCCCCC"/>
    <Setter Property="FontFamily" Value="pack://application:,,,/MyUIControls;component/./Fonts/#Noto Sans"/>
</Style>

我尝试直接从代码或通过绑定更新

底线是:
当设置时,每次更新文本时都会出现实例(永远)。当我不设置属性时,内存稳定。
(顺便说一下,当我使用

看起来像是内存泄漏,但我找不到任何相关的参考。
有什么建议可以解决吗?


我知道这是一个老问题,但出于好奇,你是否尝试将字体资源放入应用程序资源字典中?它会泄漏吗? <FontFamily x:Key="AppFont">pack://application:,,,/MyUIControls;component/./Fonts/#Noto Sans</FontFamily> 然后使用<Setter Property="FontFamily" Value="{StaticResource AppFont}" />. - Endrju
根据@Endrju的建议,本质上创建了一个字体族对象的单例,保存在资源字典中,这应该解决了内存问题。 - Robetto
1个回答

19

当使用从嵌入资源或相对路径获取的FontFamily时,会泄漏UnmanagedMemoryStreams。而当FontFamily来自系统字体或绝对路径时,则不会泄漏。

您可以在此处查看并下载可以重现问题的项目。

解决方法:对于资源字体,将字体保存至临时文件夹并使用存储字体的绝对路径。对于相对路径字体,解析并使用绝对路径。


1
奇怪。这是一个错误吗,还是你可以处理字体? - Aron
@Aron:看看WPF团队的评论,他们说它是这样的。 - israel altar
3
天啊,他们不会修复它(指更高影响力的焦点错误),实际上意味着:专注于开发人员更容易注意到的错误... - RoeeK
4
能否使用绝对路径作为资源来使用自定义字体?或者说我们应该放弃将自定义字体作为嵌入式资源来使用吗? - Zsolt
1
重现问题的项目链接已经失效,我在Microsoft Connect上找不到它。有人有可用的链接或者可以展示如何重现吗? - Magnus Lindhe
1
我尝试通过AddFontMemResourceEx提供的替代方案来解决问题,具体细节请参考https://dev59.com/jazka4cB1Zd3GeqP6lP1 - nietras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接