2011-05-26 103 views
24

我在呈现线程停止呈现的wpf应用程序中遇到问题,但UI线程和辅助线程仍在泵送消息。WPF呈现线程挂起

它似乎与演示字体缓存的腐败有关,但这似乎不太可能,因为应用程序在重新启动时可以很好地恢复。

渲染线程偶尔会挂起,阻止绘图更新,但UI线程仍在泵送消息。

我们已经看到类似的问题(类似于here),当将缩放转换应用于通过删除字体缓存解决的文本块时发生,但是此特定问题不可靠重复。

诊断此问题根本原因的最佳方法是什么?

我已经打开了一个微软在connect的错误,但它不会被考虑,除非其他人投票。

+0

我看过类似的问题,对这个问题也很感兴趣! – 2011-05-26 03:10:40

+2

是否有您可以提供的半重复示例? – tofutim 2011-05-30 23:18:50

+0

不幸的是,tofutim。我们在两台不同的机器上发生了两次(我们知道)。堆栈轨迹也显示正常。 – LukeN 2011-06-01 07:25:55

回答

5

冻结被托管的ActiveX控件呈现的视频引起的。

有控制中使用的DirectShow的方式造成的DirectX挂的竞争条件。

我们通过使用procdump进行进程转储,然后在Windows debugger中打开转储文件,发现此问题。

net上寻找并检查本地调用堆栈时,出现了一个问题,即临界区指针的高位字节为零,这意味着其中一个线程正在等待一个永远不存在的临界区信号。

这使我们能够创建一个可重复的行使是开始和采空视频代码挂起。我们删除了控件,并停止了挂起。

+0

嗨,我面临同样的问题,请你详细说明哪个控件准确给了你这个错误,以及你如何使用procdump来监控它? (你使用了哪个命令?)谢谢! – 2014-07-28 14:32:00

+0

有在一个视频[通道9](http://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-9-ProcDump),这将告诉你如何使用它。如果您没有编写太多的c/C++,理解本地堆栈框架会变得更加困难。助手如何使用windbg:[作弊表](http://theartofdev.com/windbg-cheat-sheet/)和[加载.net](http://mylittlereminder.wordpress.com/2011/07/08/ windbg-load-sos-in-windbg-0x80004005 /) – LukeN 2014-07-29 01:37:02

+0

所以......你在做自由职业吗? :) – 2014-07-29 11:18:18

0

您可以使用看门狗服务在服务检测到问题时清除缓存。每当您的应用程序运行时,该服务都必须定期进行轮询。

我将首先承认这是一种次优解决方案,除非您能够在短时间内开启和关闭服务,否则您可能会很快耗尽电池。

+0

我的问题不是如何解决该问题。我正在寻找诊断根本原因的帮助。 – LukeN 2011-06-01 05:45:44

0

我认为你必须使用循环轮询来持续检查软件是否正在运行,并在软件挂起时重置它。

+0

嗨保罗,问题不在于如何解决问题。我期待找到根本原因。 – LukeN 2011-06-01 05:46:29

+0

@ luken plz向我展示我的代码我会尽力寻求这个问题 – Eljay 2011-06-03 05:16:22

1

我不知道它为什么会发生,但我曾经体验过它。在以Framework 4.0为目标的系统中运行并在较旧的机器上运行(XP,Vista)更容易。

我做了什么来解决是:

  1. 删除FontCache3.0.0.0.dat
  2. 永久禁用违规机

解决方案1在一个XP制作的字体缓存服务机。它也在Vista机器上工作,但过了一段时间后问题再次出现。

要删除FontCache3.0.0.0.dat,您需要先停止“Windows Presentation Foundation Font Cache 3.0.0.0”服务,然后才能删除该文件。在Vista中,它位于c:\ windows \ serviceprofiles \ localservice \ appdata \ local下。在XP中,它是在C:\ WINDOWS \ SYSTEM32 \文件和设置\本地服务\本地设置\应用程序数据(我可能拼错了一些文件夹)

我也发现完全禁用系统(解决方案2)影响我的.net应用程序的性能。

+0

您好帕杜,我提到这个问题看起来很相似,但在启动时恢复,似乎排除了字体缓存的问题。 – LukeN 2011-06-02 17:36:36

1

找到问题根本原因的唯一方法是从线程中进行常量日志记录,直到找到挂起的原因为止。我可以提供很多方法来做这种日志记录,但这取决于渲染线程中代码的复杂程度。在没有大量调试信息的情况下(引入足够的延迟来暂时解决问题的那种事情,不会少),你无法深入到它发生的一次。

如果你可以在VS中重复它,那么你应该使用一些控制台记录预期的麻烦部分,否则你可能不得不将它拉到文本文件中,或者将它发送到系统记录器。

你能得到它的一个简单的应用程序,只有该应用是否会其余的渲染和相关零部件,或者它只是发生(只能出现?)在完整的程序重演?

+1

该框架负责渲染线程 - 这是问题所在。有关详细信息,请参阅http://blogs.msdn.com/b/nickkramer/archive/2005/07/19/437025.aspx。本质上,应用程序挂在微软的代码中,而我的代码仍在运行,因为它应该。我有兴趣知道的是,字体缓存服务的问题实际上是否导致挂起,或者是否存在可能导致问题的WPF库内部中的另一个类似问题。如果后者是真的,我将如何去测试它(鉴于我不了解wpf或directx的内部)。 – LukeN 2011-06-06 00:32:56

+0

你能不能反映它看到它在做什么?你肯定知道反射器或ILSpy,是吗? – jcolebrand 2011-06-06 01:22:45