5

有很多主题涵盖了这个问题。但是,我有一个问题。

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

4

6 回答 6

4

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

仅当线程的整个堆栈在没有找到适用的异常处理程序的情况下展开时,异常才会被处理,因此可以引发事件的第一个位置是在线程发起的应用程序域中。

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

于 2013-03-26T23:37:39.903 回答
1

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

于 2013-03-22T12:02:45.883 回答
0

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

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

AppDomain.CurrentDomain.FirstChanceException +=
    (obj, e) => Loger.WriteError(
        e.Exception.ToString(),
        e.Exception.Message,
        "default solution"
    );
于 2013-03-23T05:43:36.090 回答
0

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

于 2013-03-22T11:35:20.637 回答
0

这是一个迟到的回复,但如果你问我,这似乎工作正常(VS2012/.NET 4.5),当然需要在调用 ExecuteAssembly 之前注册异常处理程序:(我有一个通过写入导致访问冲突的子进程到一个空引用(不安全代码)只是为了强制崩溃,它会触发下面的 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);
    }
}
于 2014-05-05T15:02:31.417 回答
0
  1. FirstChanceException火灾。
  2. 执行任何catch块。
  3. 如果没有catch块或throw在块中则UnhandledException触发

您的catch块确保UnhandledException不会触发。

于 2015-06-11T14:05:08.283 回答