如何打破 Silverlight 中未处理的异常

Posted

技术标签:

【中文标题】如何打破 Silverlight 中未处理的异常【英文标题】:How to break on unhandled exceptions in Silverlight 【发布时间】:2010-05-11 21:12:41 【问题描述】:

在控制台 .Net 应用程序中,对于没有匹配 catch 块的异常,调试器会在抛出点(堆栈展开之前)中断。 Silverlight 似乎在 try catch 中运行所有用户代码,因此调试器永远不会中断。相反,会引发 Application.UnhandledException,但在捕获异常并展开堆栈之后。要在抛出未处理的异常但未被捕获时中断,我必须启用第一次机会异常中断,这也会停止程序以处理已处理的异常。

有没有办法移除 Silverlight 的 try 块,以便异常直接进入调试器?

【问题讨论】:

有什么理由不能在 App.xaml 中中断 UnhandledException 处理程序并检查那里的异常?我知道这不太理想,但它可以为您提供所需的所有信息。 Application.UnhandledException 在展开堆栈后引发。您可以访问存储在异常对象中的堆栈跟踪,但抛出时局部变量的状态会丢失。 我预计 IntelliTrace 将在未来(SL 5?)版本中解决最后一个问题。 【参考方案1】:

实际上,这相当容易。

利用Application_UnhandledException event,您可以通过编程方式inject a breakpoint。 

using System.IO; // FileNotFoundException
using System.Windows; // Application, StartupEventArgs, ApplicationUnhandledExceptionEventArgs

namespace SilverlightApplication

    public partial class App : Application
    
        public App()
        
            this.Startup += this.Application_Startup;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();
        

        private void Application_Startup(object sender, StartupEventArgs e)
        
            this.RootVisual = new Page();
        

        private void Application_UnhandledException(object sender, 
            ApplicationUnhandledExceptionEventArgs e)
        
            if (System.Diagnostics.Debugger.IsAttached)
            
                // Break in the debugger
                System.Diagnostics.Debugger.Break();

                // Recover from the error
                e.Handled = true;
                return;
            

            // Allow the Silverlight plug-in to detect and process the exception.
        
    

【讨论】:

抱歉 - 我刚刚重新阅读了这个问题,并意识到您已经取消了这种方法,因为它不能满足您的需求。不过,我会在此处留下答案,因为其他人可能会觉得它有帮助。【参考方案2】:

在您的 Web 项目中,确保选中 Silverlight 应用程序的调试复选框。您将在 Web 应用程序的“属性”->“Web”选项卡下找到该设置。

在 VS2008 中,按 Ctrl+Alt+E 调出“异常”窗口,选中“公共语言运行时异常”的 Thrown 列下的框。在 VS2010 中,我不认为该快捷方式有效,因此您需要从下拉菜单中转到 Debug->Exceptions。

我不确定这是否正是您正在寻找的,但希望对您有所帮助!

【讨论】:

感谢您的回答。我在我的问题中描述了这个解决方法。它的问题是调试器会停止程序,即使是在调用堆栈中的某个地方处理的异常。【参考方案3】:

麻烦制造者是 DispatcherOperation.Invoke() 方法。它看起来像这样:

internal void Invoke()

    try
    
        this._operation.DynamicInvoke(this._args);
    
    catch (Exception exception)
    
        Error.GetXresultForUserException(exception);
    

“catch all”子句阻止调试器介入。Silverlight 缺少类似于 Windows 窗体的 Application.SetUnhandledExceptionMode() 方法的东西。并且没有检查调试器是否正在运行,Winforms 会执行其他操作。

这并不让我觉得很难添加,我建议您在 connect.microsoft.com 上发布功能请求

同时,除了 Debug + Exceptions 没有其他可用选项,勾选 Thrown 复选框以强制调试器在抛出异常时停止。为真正的例外保留例外。

【讨论】:

【参考方案4】:

我使用 CTRL+ALT+E(调试 > 异常)方法强制调试器在抛出时中断,但我会根据需要和尽可能有针对性地这样做。

如果我试图追踪异常,我会在应用程序第一次崩溃后在输出窗口 [Debug] 中查找它的类型。然后,我将仅使用对话框右侧的“查找”按钮为该异常类型打开“抛出时中断”。

它并不完美,但它就像我得到的一样经过过滤。

【讨论】:

【参考方案5】:

启用“仅我的代码”调试接近于我想要的行为。见

http://forums.silverlight.net/forums/p/20678/72192.aspx

https://connect.microsoft.com/VisualStudio/feedback/details/356687/visual-studio-breaks-on-unhandled-exceptions-incorrectly-in-silverlight#tabs

【讨论】:

【参考方案6】:

并非所有浏览器都支持调试 Silverlight。

例如,我无法用 Firefox 或 Chrome 调试它,它只能在 IE 中正常工作。 :(

如果这不是您的问题,请忽略此答案。

【讨论】:

【参考方案7】:

单击调试,选择异常,将公共语言运行时异常标记为已抛出。 我遇到了同样的问题,它为我解决了问题

【讨论】:

以上是关于如何打破 Silverlight 中未处理的异常的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 WCF 线程中未处理的异常使进程崩溃?

Silverlight 中未显示某些自定义字体

Android 捕捉app系统中未处理的异常

无法在 aynctask 中未调用 Looper.prepare() 异常的线程内创建处理程序

PyQt5 中未处理的异常

在多线程 C++11 程序中未处理异常时会发生啥?