渲染文本时WPF应用程序冻结(wpfgfx问题)

时间:2014-09-13 11:20:23

标签: wpf windows caching fonts text-rendering

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%,双核系统)并且唯一的方法是停止是通过任务管理器杀死它。
  • 然后我安装并尝试运行最新版本(v4) - 它的行为与上面的v3类似

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

技术位,仅供参考:

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

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

  • 与启动相关:应用程序在启动时几乎不执行任何操作。它只显示某种形式的启动/欢迎屏幕。除了一个漂亮的用户界面和一个按钮之外,没有任何逻辑。用户无法按下该按钮。当应用程序启动时,屏幕为黑色且没有内容,甚至没有启动/欢迎图像。

追踪和观察:

我专注于TextBox部分,因为它更精细 我已经让应用程序再次冻结,并使用ProcessHacker检查了线程 除了典型的线程,一个坐在忙碌的线程:

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

WPF层本身肯定存在问题。 DetachFromHWND告诉我几乎没有,但MilGlyphRun肯定是关于文本呈现。 尝试渲染文字时会冻结。我已经检查过旧版本应用程序的黑屏,但我无法抓住它,因为应用程序没有被冻结,只是黑色。

所以..

  • 我已经应用了所有挂起的更新(例如,其中150个,大约800 Mb,其中大多数是OS和.Net框架)
  • 我已尝试重新安装所有视频驱动程序

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

所以,重点关注问题。它无法呈现文本。听起来很明显,因为当用户将一个角色输入文本框时它会陷入僵局,但它不明显!向用户呈现了大量不同的TextBoxes,直到他最终到达PasswordBox。所有TextBoxes都运行正常,只有这一个失败。为什么应用程序的旧版本显示黑屏,新版本显示" welcome"屏幕正常吗?这些问题怎么相关?

1 个答案:

答案 0 :(得分:7)

连接是: Windows Presentation Foundation字体缓存服务。

来源:

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

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

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

并删除所有类似FontCache.dat的文件。源文章只提到了一个文件(FontCache3.0.0.0.dat,但在我的情况下,大约有8个文件具有相似的命名约定)。

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