我正在开发Windows应用商店应用。目前,我正在按照this blog post中的描述进行间歇性挂起。问题似乎是没有足够的空间给予其余定义的列宽和TextBlock
试图自己格式化(可能是由于省略号处理)。当发生这种情况时,我的应用程序会无限期地挂起。
我对如何解决问题的问题较少(因为它似乎在博客文章中有相当好的描述),而是如何找到问题。我在Hub页面上有一个相当规律的(大约五分之一或十个初创公司),所以我一直在那里(因为它是最值得注意的问题实例),但它是一个真正的Heisenbug,因为它似乎永远不会在调试时(或当你寻找它时)发生。
那么,我如何找到有问题的代码呢?我需要寻找一种模式(ColumnWidth="*"
?)。有没有更简单的方法来解决这个问题,例如更改基本样式以删除博客文章中列出的可能有问题的属性之一?
这似乎可能是由另一个问题引起的,但这似乎是现在最可能/似乎合理的(就像我的中心有类似情况那样)。
此外,有没有办法追踪这种情况何时发生? MSFT在挂起时提供崩溃转储,但它们似乎根本没有提供任何信息(最重要的是它们只在它们发生后5天出现,这不太理想)。
谢谢!
答案 0 :(得分:2)
这是一个复杂的问题要回答。
首先,我认为您已经确定了WinRT的真正问题。您推测布局子系统似乎忙于计算您的布局,并且基于某些条件发生在大约20%的时间内它在任何合理的时间内都没有完成。合理的猜测。
问题是,在调试期间不会发生此类事件。在我的个人开发经验中,调试中未发生的错误与99.99%的时序相关。在第二个过程开始之前,某些事情没有完成。调试允许那些第一个很长的过程完成。
这是一个真正的计算机科学问题,而不是WinRT或Windows 8问题。为此,我可以在没有任何代码示例的情况下为您提供最佳答案(为什么没有代码示例?)是我遇到同样困境时采用的典型方法。我希望它至少有一点帮助。
从大脑开始。
我总是和开发人员开玩笑说在调试器外面可以做多少调试 - 在你的脑海里。精神上走在你的应用程序的管道,并寻找可能导致死锁的竞争条件依赖项。信不信由你,这解决了调试器永远无法捕获的许多问题 - 因为调试器解除了时序依赖性。
接下来是简单。
问题越复杂,你就越不可能找到罪魁祸首。对于XAML应用程序,我倾向于首先删除或禁用值转换器。然后,我希望删除数据模板。如果你有元素绑定,那么下一步。如果简化XAML确实有帮助 - 那只是开始搞清楚。如果没有,事情会变得更容易。
您的代码可以通过几次击键禁用,并被判有罪或无辜。我发现这是你问题的最有可能的地方,也是我们努力工作以保持简单,干净和最小化的原因。在那之后,有视图模型。虽然你的视图模型不是不可能的,但你确实还需要检查,它可能不是你邪恶的根源。
最后,还有应用程序管道加载您的页面,加载您的数据或执行其他任何操作。一步一步你唯一真正的选择是慢慢删除你的应用程序中的东西,直到你没有看到问题。删除问题,虽然没有解决它。这是一个基于您的应用程序及其中的逻辑的案例。现实是,您可能会在删除XAML时看到问题,而真正的问题出在视图模型或其他地方。
我到底在说什么?你要求的银弹真的不在那里。有几种Microsoft工具甚至更多第三方工具可以查找瓶颈,延迟问题,代码速度慢和内容 - 但实际上,您所描述的场景是简单的编程。我不说你不是一个bug的受害者。我说,凭借我们掌握的信息,这就是我能为你做的一切。
你会明白的。
要做的第三件事是为您的应用添加日志记录和工具。
祝你好运。
答案 1 :(得分:1)
鉴于Jerry已经在更高级别回答了这个问题,我想我会在较低级别的答案中加上你的问题表达方式使我认为你感兴趣。我想首先我想谈谈最后一项这是转储文件。有一种机制可以通过Windows错误报告获取Microsoft提供的“疯狂”进程的转储文件。如果您想从失败的客户端进程收集转储文件,您可以注册Windows错误报告(我必须承认我从未真正做过它,但我确实调查了它并试图让我现在的雇主允许我这样做,但它没有成功结束)。要注册,请转到Establish a Hardware/Desktop Account Page。
至于如何处理转储文件,你可能想要下载windows的调试工具(Windows SDK download的一部分)和/或the Debug Diag Tool(我必须承认)对于Windows用户来说,我比Debug Diag用户更像是一个调试工具。这些将为您提供工具,以便在较低级别查看正在进行的操作。显然,你只能访问私有Microsoft符号,但你可以访问公共符号,通常这些符号足以让你对问题区域有很好的了解。
您的主要工具将取决于问题的可重现性。如果它只能在某些客户端计算机上重现,那么您将不得不依赖于查看您可能从Windows错误报告中获取的单个转储文件。在这种情况下,我要做的是使用相应版本的Windbg(x86或x64)打开它,并查看转储时所发生的事情。取决于你的精明程度取决于你能走多远。可能一个简单的启动器将运行
.symfix
.reload
.loadby sos clr
!EEStack
这将加载Microsoft公共符号,用于处理托管代码检查的sos扩展名dll,然后将为进程中的每个线程转储堆栈的内容。通过查看调用堆栈中出现的方法的名称,您可能至少可以很好地了解发生锁定的代码区域。
你可以走得更远,因为Windbg提供了进入死锁分析的能力(例如,有一个可用于Windbg的扩展,称为sosex,提供命令!dlk
,有时可以自动检测单个转储文件中的死锁。要将扩展dll加载到Windbg,您只需下载它然后调用.load fullpathtodll
)。如果问题在本地可重现,您甚至可能在WPA / WPR上更成功,或者如果您真的很幸运,那么简单的procmon跟踪。这些工具确实具有相当不错的入门门槛,因为它们需要一些时间来学习。但如果你真的对这个主题感兴趣,你最好的资源将是Channel9上的Defrag Tools系列和Mario Hewardt的任何东西(特别是他的书“Advanced .Net Debugging”)。再一次,熟悉这些工具可能需要花费大量时间,但至少如果您只知道如何从转储文件中转储堆栈的内容,您有时可以从中获得所需的内容,因此基本了解这些工具也很有用。