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();  
        }
    }
}

このサンプルはクラスとボタン イベントです。
しかし、ページやその他のイベントでも同じ問題があります。
例外をスローするクラスが Window Loaded イベントで作成されたとしても、詳細はありません。
e.Exception.GetBaseException() を調べましたが、まだ情報がありません。
イライラするのは、例外がスローされるデバッグ モードです。Visual Studio で完全なスタック トレースを表示できますが、App_DispatcherUnhandledException に到達するまでにそのスタック トレースはなくなります。

PDB ファイルを含めてみましたが、修正されませんでした。

4

2 に答える 2

1

リリース モードでは、多くのメソッドがインライン化されるため、コール スタックに含まれるメソッドはデバッグ モードよりも少なくなります。これは、例外でクラスとメソッドが消える場所です。

ただし、必要なすべての 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 に答える