应该在哪里订阅AppDomain.UnhandledException?

时间:2015-05-19 11:59:22

标签: c# .net wpf

建议的重复约为DispatcherUnhandledException,而不是AppDomain.CurrentDomain.UnhandledException

原始

AppDomain.UnhandledException应该订阅哪里? MSDN上的示例只是在Main中显示,这是我在Winforms中所做的:我在 Program.Main 订阅了它:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

但是我无法在WPF中找到适合它的地方,其中隐藏了Main。我已经搜索过,但主要是讨论是否订阅它,假设读者现在在哪里。

3 个答案:

答案 0 :(得分:3)

假设您使用Visual Studio中的默认模板创建了项目,您应该有一个名为app.xaml的文件,并在其下面有另一个名为app.xaml.cs的文件。

App课程内,您可以在OnStartup的开头添加它(以及Dispatcher.UnhandledException):

protected override void OnStartup(StartupEventArgs e)
{
    // don't forget to call base implementation
    base.OnStartup(e);

    Dispatcher.UnhandledException += Dispatcher_UnhandledException;
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}

实际上,Dispatcher.UnhandledException在大多数情况下应该足够了。这意味着您可以完全跳过AppDomain.CurrentDomain.UnhandledException。注册到AppDomain.CurrentDomain.UnhandledException的唯一原因是在主UI线程以外的线程中引发异常。但我认为更好的做法是在各自的线程中实际捕获这些异常。

答案 1 :(得分:2)

WPF中的Main()入口点是从App.xaml源文件自动生成的。您必须订阅该事件的最早机会在App.xaml.cs中的App类的构造函数中:

public partial class App : Application {
    public App() {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
        // etc...
    }
}

然而,这并非完美",您无法检测Application类的字段初始值设定项中的任何失败。除了在Application类中使用的类型的任何JIT编译失败之外,缺少程序集或版本控制问题是常见的麻烦制造者。

为避免遗漏这些错误,您需要放弃自动生成的代码并编写自己的Main()方法。假设您没有大量修改app.xaml文件。从项目中删除该文件并添加一个新类,我建议使用Program.cs :)并使其看起来与此类似:

using System;
using System.Runtime.CompilerServices;
using System.Windows;

namespace WpfApplication1 {
    class Program {
        [STAThread]
        public static void Main(string[] args) {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            Start();
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void Start() {
            var app = new App();
            app.Run(new MainWindow());
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            // etc..
        }
    }

    public class App : Application {
        // etc..
    }
}

答案 2 :(得分:1)

您可以覆盖OnStartup中的App.xaml.cs方法,这是您与[{1}}方法最接近的方法(如果愿意,可以使用Main构造函数)

App

请注意,这需要您省略public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // register the event handler here AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; } } 并自己打开StartupUri