【问题标题】:WPF application freezes when rendering text (wpfgfx issues)呈现文本时 WPF 应用程序冻结(wpfgfx 问题)
【发布时间】:2014-11-07 11:34:51
【问题描述】:

TL;DR:

  • 应用程序使用 WPF 构建,在 .Net 3.5 上运行
  • 最新和旧版本的应用程序可以在许多不同的机器上正常运行
  • 在一台特定的机器上,它以一种奇怪的方式出现故障:
    • 两者都不启动,显示黑屏而不是“欢迎”屏幕;在那个黑屏上什么都做不了
    • 或确实启动并正常工作,直到出现 TextBox 并且用户开始在其中输入文本;然后应用程序立即挂起

背景:

我在 .Net 3.5 上构建了一个 WPF 应用程序。我已经检查了具有不同操作系统的各种机器上的应用程序,从 Windows XP 到 Windows 7 - 它运行良好,没有错误等。它在我客户的几台目标机器上也能正常工作,再次包括 XP 和 W7。

但是,在一台机器上,它突然停止工作。我的客户把机器寄给我,这样我就可以调查了。从其驱动器上的文件中,我可以看到有较旧的版本,它们被客户使用了几个月。我还看到最新版本尚未安装在这台机器上。所以,我先尝试运行旧版本,看看有什么问题。

用户看到了什么:

  • 应用程序的最旧版本(例如 v1、v2)根本无法运行。当它们启动时,应用程序显示的唯一内容是......绝对完全黑色的窗口。应该有一个“欢迎”屏幕,由少量图像和标签以及一个按钮组成。该应用程序未冻结,它是“响应式”的(Win7 可以与其通信,窗口变暗)。
  • 最后一个(但不是最新的,我们将其命名为 v3)应用程序运行良好,一切都可点击,功能正常,除了一个。当要求用户提供密码时,会在弹出窗口中向用户显示单个 TextBox。当用户在该文本框中输入至少一个字符时,应用程序会冻结。它甚至在呈现密码的蒙面“*”之前就冻结了。完全冻结,应用程序停止响应(窗口变暗并且操作系统想要关闭它),CPU 达到 100%(实际上是 50%,双核系统)并且唯一的方法stop 是通过任务管理器杀死它。
  • 然后我安装并尝试运行最新版本 (v4) - 它的行为就像上面的 v3 一样

  • 我还尝试重新安装所有版本,只是为了确保 .EXE/.DLL 文件没有损坏 - 没有更改(v1/2 - 黑色,v3/4 - 冻结文本)

技术位,仅供参考:

  • 该应用程序非常简单,一个没有共享库和共享配置的可执行文件。只是没有办法最新版本可以与旧版本交互。说真的,我故意让应用程序可以“直接复制”,并且可以将多个实例安全地保存在不同的文件夹中。
  • 应用程序的所有版本(v4、v3、v2、v1)在所有其他计算机上都能正常运行,以及各种版本的 Windows
  • 问题与用户文件或配置无关,我尝试将它们从有问题的机器复制到健康机器,问题不再重复

  • 与密码框相关:代码中绝对没有可能产生死锁或冻结的事件处理程序。密码文本框没有文本更改处理程序。我的代码只有在按下“确定”按钮后才会读取文本。当用户输入第一个字符时,应用程序立即冻结, 用户甚至没有机会按“确定”

  • 与启动有关:应用程序在启动时几乎什么都不做。它仅显示某种形式的启动/欢迎屏幕。除了漂亮的 UI 和一个按钮外,没有其他逻辑。用户没有机会按下该按钮。应用启动时,屏幕是黑色的,没有任何内容,甚至没有启动画面/欢迎图像。

追踪与观察:

我专注于 TextBox 部分,因为它更细化。
我让应用程序再次冻结,并使用 ProcessHacker 检查了线程。
除了典型的线程,一个线程正忙着旋转:

 wpfgfx_v0300.dll MilGlyphRun SetGeometryAtRenderTime
 wpfgfx_v0300.dll MilGlyphRun SetGeometryAtRenderTime
 ...
 wpfgfx_v0300.dll MilContent DetachFromHWND

这肯定是 WPF 层本身的问题。 DetachFromHWND 告诉我几乎没有,但 MilGlyphRun 肯定是关于文本渲染的。 它在尝试渲染文本时冻结。我检查了旧版本应用程序的黑屏,但我无法捕捉到它,因为应用程序没有冻结,只是黑屏。

所以..

  • 我已经应用了 所有 待处理更新(例如,其中 150 个,约 800 Mb,其中大部分用于操作系统和 .Net 框架)
  • 我已尝试重新安装所有视频驱动程序

没有变化,仍然黑屏,仍然冻结。

所以,回到问题上来。它未能呈现文本。听起来很明显,因为当用户在文本框中输入一个字符时它会死锁,但这并不明显!用户看到了大量不同的TextBoxes,直到他最终到达PasswordBox。所有TextBoxes 工作正常,只有这个失败。为什么旧版本的应用程序显示黑屏,而新版本的应用程序正常显示“欢迎”屏幕?这些问题怎么可能相关?

【问题讨论】:

    标签: wpf windows caching fonts text-rendering


    【解决方案1】:

    连接是:Windows Presentation Foundation Font Cache服务。

    来源:

    WPF 使用字体缓存服务,作为单独的进程运行,用于缓存字体。每当您的 WPF 应用程序需要绘制一些文本时,它可能会向缓存服务请求字体。有时,字体缓存可能会损坏,然后会/可能会随机影响任何 WPF 应用程序

    不幸的是,重新启动服务是不够的。发生这种情况时,您必须删除此服务保留在磁盘上的所有FontCache 文件。在删除它们之前,您必须停止 "Windows Presentation Foundation Font Cache 服务(或您的语言中的任何名称,例如波兰语中的 Usługa buforowania czcionek platformy Windows Presentation Foundation..)。然后,转到

    • Win7:%systemdrive%\Windows\ServiceProfiles\LocalService\AppData\Local\
    • 远景:%systemdrive%\Windows\ServiceProfiles\LocalService\AppData\Local\
    • WinXP:%systemdrive%\Documents and Settings\LocalService\Local Settings\Application Data

    并删除所有看起来像FontCache.dat 的文件。源文章只提到了一个文件(FontCache3.0.0.0.dat,但在我的例子中,大约有 8 个文件具有类似的命名约定)。

    删除它们并重新启动服务后,我的应用程序的所有版本都再次正常运行。没有黑屏,文本框没有冻结。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-23
      • 2011-11-07
      • 2020-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多