AppDomain未处理的异常

本文关键字:异常 未处理 AppDomain | 更新日期: 2023-09-27 18:05:12

关于这个问题有很多话题。但是我有一个问题。

我像这样将程序集加载到新的AppDomain中:

public void Run()
{
    //There's the problem.
    //As Panos Rontogiannis mentioned the thread is created in default AppDomain
    new Thread(RunApp).Start();
}
private void RunApp()
    try
    {
        AppDomain.CreateDomain("domain name").ExecuteAssembly("path to assembly");
    }
    catch (Exception _e)
    {
        MessageBox.Show("Unhandled Exception.'n" + _e);
    }
}

在加载程序集的Main方法中,我将处理程序订阅到UnhandledException事件:

AppDomain.CurrentDomain.UnhandledException += handleException;

处理器本身:

public static void handleException(object a_s, UnhandledExceptionEventArgs a_args)
{
    var _e = (Exception)a_args.ExceptionObject;
    //Static loger class method
    Loger.WriteError(_e.GetType().ToString(), _e.Message, "default solution");
}

但是,无论在加载的程序集中抛出异常,处理程序都不会参与其中。我只在默认的AppDomain(第一个try{} catch{})中捕获异常。

AppDomain未处理的异常

最可能的是,您不能在新的AppDomain中处理异常的原因是它不是从在该AppDomain中创建的线程抛出的。从AppDomain的文档。UnhandledException看起来不是很直接。有趣的部分如下:

异常只有在线程的整个堆栈已被处理时才未处理在没有找到适用的异常处理程序的情况下展开,因此首先可以引发事件的地方是在应用程序域中线程启动。

现在,如果执行抛出代码的线程是在主AppDomain中创建的(就像控制台应用程序的主线程),那么你应该在主AppDomain中添加处理程序。注意,如果抛出异常的类型没有加载到主AppDomain中,. net的Assembly Loader将尝试从应用程序的基本目录和探测路径加载它。如果这些与子AppDomain不相同,则不会解析程序集并抛出(其他)异常。

发生这种情况的原因有很多。在http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx上的事件文档详细介绍了这种复杂性,如果没有什么是适用的,请发布repro代码好吗?

我的猜测是处理异常时没有调用处理程序。即由上部try{}catch{}

我真的不明白为什么处理程序没有被调用。

我最终在加载程序集的主方法中使用了FirstChanceException而不是UnhandledException。这样的:

AppDomain.CurrentDomain.FirstChanceException +=
    (obj, e) => Loger.WriteError(
        e.Exception.ToString(),
        e.Exception.Message,
        "default solution"
    );

这是一个迟到的答复,但这似乎工作很好,如果你问我(VS2012/。. NET 4.5),异常处理程序需要在ExecuteAssembly被调用之前注册:(我有一个子进程,通过写入null ref(不安全代码)来导致访问冲突,只是为了强制崩溃,它触发了下面的HandleException:

public static void HandleException(object a_s, UnhandledExceptionEventArgs a_args)
{
    var _e = (Exception)a_args.ExceptionObject;
    Console.WriteLine(_e.GetType().ToString(), _e.Message, "default solution");
}
public void StarProcessWithinAppDomain(string fileName)
{
    try
    {
        // New appdoamin / check exception isolation level 
        AppDomain sandBox = AppDomain.CreateDomain("sandBox");
        try
        {
            AppDomain.CurrentDomain.UnhandledException += HandleException;
            sandBox.ExecuteAssembly(fileName);
        }
        catch (Exception ex)
        {
            Console.WriteLine("An error occurred (inner) within AppDomain, executing '"{0}'":" + "'n" + ex.Message, fileName);
        }
        finally
        {
            AppDomain.Unload(sandBox); 
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("An error occurred within AppDomain, executing '"{0}'":" + "'n" + ex.Message, fileName);
    }
}
  1. FirstChanceException着火
  2. 所有catch块都被执行。
  3. 如果块中没有catch块或throw块,则UnhandledException触发

你的catch块确保UnhandledException不触发