3

全局错误处理问题。
想要获取包含引发异常的行的详细信息。
如果抛出错误的类是在 MainWindow 的 ctor 中创建的,那么它会报告异常的类名和行号。
但是引发异常的类是在事件处理程序中创建的,然后是零细节 - 甚至不报告引发异常的类的名称。如何从由事件处理程序初始化的对象的异常中获取详细信息?

namespace GlobalErrorHandler
{
    public partial class App : Application
    {
        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            MessageBox.Show("App_DispatcherUnhandledException Error." + e.Exception.Message + " " + e.Exception.InnerException, "Error");
            e.Handled = true;
            //if (MainWindow != null) MainWindow.Close();
        }
        public App()
        {
            this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
        }
    }
}

<Window x:Class="GlobalErrorHandler.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="300">
    <Grid>
        <Button Content="Class1 from Main" Click="Button_Click_Class" 
                Height="20" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    </Grid>
</Window>

namespace GlobalErrorHandler
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //Class1 MyClass1 = new Class1();    // this gives line detail
            //throw new Exception();             // this gives line detail
        }

        private void Button_Click_Class(object sender, RoutedEventArgs e)
        {
            Class1 MyClass1 = new Class1();      // this does NOT give line detail
        }
    }
}

namespace GlobalErrorHandler
{
    class Class1
    {
        public Class1()
        {
            throw new Exception();  
        }
    }
}

此示例是一个类和一个按钮事件。
但是 Page 或任何其他事件也存在同样的问题。
即使引发异常的类是在 Window Loaded 事件中创建的,但细节为零。
查看了 e.Exception.GetBaseException() 仍然没有信息。
令人沮丧的是在抛出异常的调试模式下,我可以在 Visual Studio 中查看完整的堆栈跟踪,但是当它到达 App_DispatcherUnhandledException 时,该堆栈跟踪已经消失了。

尝试包括 PDB 文件,但没有解决它。

4

2 回答 2

1

在 Release 模式下,许多方法是内联的,因此调用堆栈包含的方法比在 Debug 模式下少。这是您的类和方法在异常中消失的地方。

但是,如果您包含所有必要的 PDB 文件,则应保留异常的堆栈跟踪,包括行号信息。因此,请确保在运行应用程序时,包含 Page 类的程序集的 PDB 文件存在并且可以访问。

于 2013-09-01T08:37:15.827 回答
1


堆栈跟踪就在那里

public partial class App : Application
{
    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine((e == null).ToString());
        System.Diagnostics.Debug.WriteLine("e.ToString() " + e.ToString());
        System.Diagnostics.Debug.WriteLine("e.Exception.GetBaseException().Message " + e.Exception.GetBaseException().Message);
        System.Diagnostics.Debug.WriteLine("e.Exception.GetBaseException().InnerException " + e.Exception.GetBaseException().InnerException);
        System.Diagnostics.Debug.WriteLine("e.Exception.GetBaseException().Source " + e.Exception.GetBaseException().Source.ToString());
        System.Diagnostics.Debug.WriteLine("e.Exception.StackTrace " + e.Exception.StackTrace.ToString());
        System.Diagnostics.Debug.WriteLine("e.Exception.GetBaseException().StackTrace " + e.Exception.GetBaseException().StackTrace.ToString());
        StringBuilder sb = new StringBuilder();
        if (e.Exception.InnerException != null)
        {
            sb.AppendLine("InnerException");
            sb.AppendLine(e.Exception.InnerException.Message);
            if (!string.IsNullOrEmpty(e.Exception.InnerException.StackTrace))
            {
                int count = 0;
                foreach (string line in e.Exception.InnerException.StackTrace.Split('\n'))
                {
                    sb.AppendLine(line.Trim());
                    count++;
                    if (count > 3) break;
                }
            }
        }
        sb.AppendLine("OuterException");
        sb.AppendLine(e.Exception.Message);
        if (!string.IsNullOrEmpty(e.Exception.StackTrace))
        {              
            int count = 0;
            foreach (string line in e.Exception.StackTrace.Split('\n'))
            {
                sb.AppendLine(line.Trim());
                count++;
                if (count > 3) break;
            }
        }
        MessageBox.Show(sb.ToString(), "App_DispatcherUnhandledException");
        e.Handled = true;
        if (MainWindow != null) MainWindow.Close();
    }
    public App()
    {
        this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
    }
}
于 2013-09-02T20:03:14.043 回答