如果在事件处理程序中创建了抛出异常的对象,则全局事件处理程序没有详细信息

时间:2013-08-31 21:54:06

标签: .net wpf exception-handling

全局错误处理问题 想要获得包含抛出异常的行的详细信息 如果抛出错误的类是在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();  
        }
    }
}

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

尝试包含PDB文件但没有修复它。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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);
    }
}