【问题标题】:Creating second-level AppDomain hangs创建二级 AppDomain 挂起
【发布时间】:2013-01-10 13:34:35
【问题描述】:

我有两个带有 Main 方法的程序集。

  • 第一个执行另一个。
  • 第二个程序集在新的 AppDomain 中创建一个对象。
  • 该对象即将创建文件或在屏幕上打印某些内容。

第一个程序集(简化示例):

class MainClass
{
    public static void Main(string[] args)
    {
        var domain = AppDomain.CreateDomain("server");
        new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
        new ManualResetEvent(false).WaitOne(); //wait forever
    }
}

第二个:

class MainClass
{
    public static void Main(string[] args)
    {
        var domain = AppDomain.CreateDomain("name");
        Console.WriteLine ("A");

        domain.CreateInstance(Assembly.GetExecutingAssembly().FullName,
            typeof(Run).FullName, false, 0, null, 
            new object[0], null, new object[0]);

        Console.WriteLine ("B");
        new ManualResetEvent(false).WaitOne();
    }
}

class Run
{
    public Run()
    {
            File.Create("something");
            Console.WriteLine ("C");
    }
}

结果因我执行的程序而异。

如果我运行 second Main,我会得到:

A
C
B

然后文件就创建好了。我将其视为第二个应用程序有效的证据。

当我运行 first Main 时,我只得到:

A

并且文件没有出现。应用程序不会崩溃,但会挂起。

我已经在 .NET 4 和 Mono 2.10.9 和 3.0.3 (~git head) 上验证了它。

这是为什么呢?我怎么能覆盖这个问题?

==EDIT==

(在 .NET 上测试)

我越来越糊涂了。

我对@9​​87654327@ 有疑问。当二进制文件在保存文件夹中时,一切似乎都很好(在 .NET 4.0 上测试过,但我也假设为单声道)。

当我使用相对路径或不同目录的路径时,结果如下:

  • 在 Visual Studio 2010 的调试中,我得到 FileNotFoundException但显示的是 A

消息:

Could not load file or assembly 'test2, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies.

在第一次组装时出现异常:

new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
  • 在不进行调试的情况下运行时,仅打印 A,但没有任何反应。

所以找到了程序集(打印了 A),但不知何故出现了异常。

我真的不知道为什么。某种权限问题?如何克服这种情况?

【问题讨论】:

  • 如果删除 File.Create 会发生什么?
  • 我检查过,没有任何变化,应用程序仍然挂起。我已经添加了这个文件,所以我肯定会看到应用程序的一些效果 - 我不知道 Console.WriteLine 是否真的会在这种情况下写入。
  • 无法重现 (.NET 4.5)。在这两种情况下,所有 3 个WriteLines 都会发生。
  • 调试时执行在哪里停止?
  • @Dhawalk - 我现在无法验证,但我会在明天尝试。我进行了编辑,因为在 Mono 上结果有点不同。达米安——同样,我明天试试。

标签: c# .net mono appdomain


【解决方案1】:

我曾经遇到过类似的问题(我没有做同样的事情,但是从第二个域创建第三个域的失败使我脑海中浮现出记忆,然后 FileNotFoundException 有点证实了“我的恐惧”)。

没有什么好证据解决不了的。 正如 MSDN 所述:http://msdn.microsoft.com/en-us/library/system.security.policy.evidence.aspx

证据 定义构成安全策略决策输入的信息集。这个类不能被继承。

那么就这样做吧:

class MainClass
{
  public static void Main(string[] args)
  {  
    var currentEvidence = AppDomain.CurrentDomain.Evidence;
    var domain = AppDomain.CreateDomain("server", securityInfo: currentEvidence);
    new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
    new ManualResetEvent(false).WaitOne(); //wait forever
  }
}

如果您计划启动第四个域(等等),请继续将证据从一个“信任者”传递给另一个“受托者”:

class MainClass
{
  public static void Main(string[] args)
  {
    var evAgain = AppDomain.CurrentDomain.Evidence;
    var domain = AppDomain.CreateDomain("name", securityInfo: evAgain);
    Console.WriteLine ("A");

    domain.CreateInstance(Assembly.GetExecutingAssembly().FullName,
        typeof(Run).FullName, false, 0, null, 
        new object[0], null, new object[0]);

    Console.WriteLine ("B");
    new ManualResetEvent(false).WaitOne();
  }
}

希望这是问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多