我在Windows 7上使用.NET 4.5,可能会发现内存泄漏.
我有一个TextBlock(不是TextBox- 它不是Undo问题),它每秒都会改变它的值(CPU使用率,时间等等).
使用.NET Memory Profiler(并通过简单地观察任务管理器)我注意到内存不断增长.为了更准确,我看到越来越多的实时实例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>
Run Code Online (Sandbox Code Playgroud)
我尝试Text直接从代码或通过Binding 更新属性,它的行为方式相同.
底线:
当FontFamily设置时,UnmanagedMemoryStream每次我更新文本时都会继续(永远)继续实例.当我没有(设置FontFamily属性)时,内存是稳定的.
(顺便说一句,它发生在我使用Label而不是TextBlock那样)
它看起来像一个内存泄漏,但我找不到任何关于它的参考.
有关如何解决的任何建议?
在 WPF 中,我们希望将ttf字体用作嵌入资源,而无需将它们复制或安装到系统中,也无需实际将它们写入磁盘。没有内存泄漏问题。
没有详细说明的解决方案:
由于 WPF 内存泄漏,在这种情况下可用:
只能通过AddFontMemResourceEx在 GDI 中从内存和进程安装字体。由于这会为该过程安装字体,因此它也应该适用于 WPF,但是在FontFamily通过AddFontMemResourceEx. 例如:
var font = new FontFamily("Roboto");
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为它不会给出任何错误,但字体实际上并没有改变,一些行间距和其他指标发生了变化,但由于Segoe UI某种原因字体看起来完全一样。
那么问题是它以及如何使用AddFontMemResourceExWPF 中安装的字体?
PS:这里是 P/Invoke 代码:
const string GdiDllName = "gdi32";
[DllImport(GdiDllName, ExactSpelling= true)]
private static extern IntPtr AddFontMemResourceEx(byte[] pbFont, int cbFont, IntPtr pdv, out uint pcFonts);
public static void AddFontMemResourceEx(string fontResourceName, byte[] bytes, Action<string> log)
{
var handle = AddFontMemResourceEx(bytes, bytes.Length, IntPtr.Zero, …Run Code Online (Sandbox Code Playgroud) 我正在尝试制作一个带有图标的网格.我将图标的字符串表示存储在数据库中,并尝试通过绑定到我的viewmodel上的Icon属性(字符串)在GridHub中显示这些图标.
当我使用这个xaml时,我得到网格中显示的实际文本
<TextBlock Text="{Binding Icon}"
FontFamily="Segoe UI Symbol"
FontSize="100"
TextAlignment="Center"
VerticalAlignment="Top"
Foreground="DarkGray"
AutomationProperties.Name="Some Label"/>
Run Code Online (Sandbox Code Playgroud)
但是这会按预期显示图标
<TextBlock Text=""
FontFamily="Segoe UI Symbol"
FontSize="100"
TextAlignment="Center"
VerticalAlignment="Top"
Foreground="DarkGray"
AutomationProperties.Name="Some Label"/>
Run Code Online (Sandbox Code Playgroud)
我的模型看起来像:
public class PermissionGroup
{
/// <summary>
/// The unique identifier for the group.
/// </summary>
public string PermissionGroupId { get; set; }
/// <summary>
/// The name of the group
/// </summary>
public string Name { get; set; }
/// <summary>
/// The page associated with the permission group
/// </summary>
public string …Run Code Online (Sandbox Code Playgroud) 好吧,所以我一直在尝试的一切都没有正确加载我的字体,我已将它们添加到 .csproj 文件中,该文件是通过切换完成的,copy to output directory所以这就是它的样子
<Resource Include="Resources\Fonts\SourceSansPro-Black.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-BlackItalic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-Bold.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-BoldItalic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-ExtraLight.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-ExtraLightItalic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-Italic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-Light.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-LightItalic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-Regular.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-SemiBold.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Fonts\SourceSansPro-SemiBoldItalic.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
Run Code Online (Sandbox Code Playgroud)
然后我在我的里面添加了引用ui-dictionary,看起来像
<FontFamily x:Key="Black" >pack://application:,,,/Resources/Fonts/#SourceSansPro-Black</FontFamily>
<FontFamily x:Key="BlackItalic" >pack://application:,,,/Resources/Fonts/#SourceSansPro-BlackItalic</FontFamily>
<FontFamily x:Key="Bold" >pack://application:,,,/Resources/Fonts/#SourceSansPro-Bold</FontFamily>
<FontFamily x:Key="BoldItalic" >pack://application:,,,/Resources/Fonts/#SourceSansPro-BoldItalic</FontFamily>
<FontFamily x:Key="ExtraLight" >pack://application:,,,/Resources/Fonts/#SourceSansPro-ExtraLight</FontFamily>
<FontFamily x:Key="ExtraLightItalic" >pack://application:,,,/Resources/Fonts/#SourceSansPro-ExtraLightItalic</FontFamily>
<FontFamily x:Key="Italic" >pack://application:,,,/Resources/Fonts/#SourceSansPro-Italic</FontFamily> …Run Code Online (Sandbox Code Playgroud)