如何在C#Windows Store(Metro)应用程序崩溃时获取有用信息(如堆栈跟踪)?

时间:2013-01-28 03:11:16

标签: c# windows-store-apps

所以我在C#(以及一般的.NET / Visual Studio)中完成了我的第一步,并开始编写一个简单的tile拼图作为可移植库,并为不同的目标平台编写UI。我从Console UI开始,转移到WPF应用程序。然后我尝试了“Windows Store”,在大多数情况下,我可以复制WPF代码,只需更改一些名称空间和方法签名。

但有些事情确实表现得有些不同,我花了一个多小时的谷歌搜索才能得到它给我任何关于我遇到的崩溃的信息。所以,例如,如果我在传统的WPF应用程序中做出类似的东西:

Storyboard.SetTargetProperty(animation, 
     new PropertyPath("{Canvas.MispelledProperty}"));

我在引发异常的确切位置获得了.NET异常。如果我在Windows应用商店应用中遇到同样的错误,我会看到这是

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
        UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
        };
#endif

(编辑:这是一个名为App.g.i.cs的文件)

然后我必须仔细查看输出以找到

WinRT information: Cannot resolve TargetProperty (Canvas.MispelledProperty) on specified object.

现在在某些情况下这可能已经足够了,但我真的很难相信这就是你所能得到的。我得到了一些与Storyboar工作方式相关的细微差别相关的问题很容易解决(完成的事件直接附加到动画中,而不像WPF对应的那样被解雇)但是现在我对这个错误完全无能为力:

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred

只是通过疯狂点击造成的,这也会导致整个应用程序崩溃。

现在我的应用程序非常简单,它可能与我处理PointerPressedPointerReleased事件的方式有关,但是如果没有更好的开始,那真的很令人沮丧。

所以我想实际的问题是:它真的应该是这样的,还是我可以配置调试器给我更多有用的信息?如果没有那样:你们在开发Windows应用商店应用时使用了哪种调试技巧/解决方法?

更新:

一开始我认为这只发生在WinRT相关的Exception上,即在CLR之外发生的地方以及没有正确包装的情况,但事实证明所有未处理的异常会将您带到App.g.i.cs而不是它们发生的地方。例如,我故意试图从一个方法中的范围中访问一个列表,以查看Visual Studio是否会在引发异常时将我带到那里,而是再次将我带到App.g.i.cs。在本地人我得到这个Windows.UI.Xaml.UnhandledExceptionEventArgs并且消息字符串有一些看起来几乎像堆栈跟踪但没有行号的信息。这是我故意错误的一个例子:

System.ArgumentOutOfRangeException
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at StorePuzzle.PuzzleRenderer.HandleTileReleased(Object sender, PointerRoutedEventArgs e)

我想要的只是Visual Studio立即将我带到引发异常的位置,而不是像“非商店应用”中那样将我带到App.g.i.cs。现在,编译器预处理器指令使它看起来像我可以关闭它(#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION)但谷歌它没有告诉我任何方式这样做。

4 个答案:

答案 0 :(得分:4)

我自己有一个非常类似的问题,关于获取堆栈跟踪和转储,我在这里问:How do I get crash logs and stack traces from WinRT apps written in C#?

与Android相比,微软从WinRT应用程序获取崩溃信息非常困难。与Android不同,没有像logcat这样的内置日志,您可以在其中看到为什么您的应用程序因简单的堆栈跟踪而崩溃。 Android将此提供给开发人员,并且不要求他们编写一行代码!

对于WinRT应用程序看起来我们都必须为这个问题推出自己的解决方案。有许多不同的地方可以发生异常,如果你想记录它们 - 如果你不记录它们,那么记录异常的重点是什么 - 它看起来会有很多工作!

本文提供了有关如何捕获XAML异常的一些解释,以便您可以记录它们:

本文解释了为什么您需要使用try / catch包装异步事件回调中的所有代码:

这个库看起来是进行日志记录的一个很好的选择,虽然它确实看起来有点沉重,因为它依赖于SQLite,如果有一个较轻的选择需要一个可能是首选的数据库。

<强>更新

微软已经在Windows 8.1中宣布了一些新的日志记录功能,文档现在在这里:

http://msdn.microsoft.com/en-us/library/windows/apps/windows.foundation.diagnostics.loggingchannel

答案 1 :(得分:4)

当您知道要查找的特定异常类型时,调试代码中的异常很容易。

从菜单中选择Debug然后Exceptions(或Ctrl+D Ctrl+E

搜索您的特定例外并查看thrown

调试器将在发生异常的代码行处停止。

我通常会在早期发现大多数例外情况。

XAML中的错误虽然是一种不同的野兽,但有时很难找到。

答案 2 :(得分:1)

关于ArgumentOutOfRangeException:Visual Studio中的调试器具有针对不同类型异常的特殊选项,您需要确保为您的异常类型选中了“Thrown”(您可以选择所有公共语言运行时异常){{ 3}}

关于WinRT:对于WinRT,我猜这是一个不同的案例。我不是WinRT的真正专家,但我认为Windows实际上与XAML的工作方式不同于WPF。 Windows做大多数工作异步(如生成控件,解析XAML等)。所以这就是为什么你大多数会从XAML获得异常而不是你试图设置属性的地方,而是作为Unhandled Exceptions。

答案 3 :(得分:-1)

Locals in VS2012

如果查看Visual Studio 2012中的“Locals”窗格,则会在调用异常时注意到名为$ exception的值。如果您深入了解它,您可以找到有关该问题的各种信息。