AppDomain未处理的异常

时间:2013-03-22 11:31:47

标签: c# exception-handling appdomain

有很多主题涉及这个问题。但是我有一个问题。

我将程序集加载到新的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{})中捕获异常。

6 个答案:

答案 0 :(得分:3)

最有可能的原因是,您无法在新AppDomain中处理异常的原因是它不是从AppDomain中创建的线程抛出的。从AppDomain.UnhandledException上的文档来看,这不是很简单。有趣的部分如下:

  

仅当线程的整个堆栈具有异常时才会处理异常   没有找到适用的异常处理程序就解开了,所以   第一个地方可以引发的事件是在应用程序域所在的地方   线程起源。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我的猜测是在处理异常时不调用处理程序。即通过上面的try {} catch {}。

答案 3 :(得分:0)

我没有真正理解为什么不调用处理程序。

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

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

答案 4 :(得分:0)

这是一个迟到的回复,但是如果你问我(VS2012 / .NET 4.5)似乎工作正常,在调用ExecuteAssembly之前需要注册异常处理程序:(我有一个导致Access的子进程通过写入空引用(不安全代码)来强制崩溃并且它触发下面的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);
    }
}

答案 5 :(得分:0)

  1. FirstChanceException开火。
  2. 执行任何catch块。
  3. 如果块中没有catch阻止或throw,则UnhandledException会触发
  4. 您的catch屏蔽确保UnhandledException无法解雇。