创建二级AppDomain挂起

时间:2013-01-10 13:34:35

标签: c# .net mono appdomain

我有两个使用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");
    }
}

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

如果我运行第二 Main,我会得到:

A
C
B

并创建文件。我认为它是第二个应用程序有效的证据。

当我运行第一个 Main时,我只得到:

A

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

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

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

== EDIT ==

(在.NET上测试)

我越来越困惑。

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

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

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

消息:

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),但不知怎的,异常出现了。

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

1 个答案:

答案 0 :(得分:0)

我有一次类似的问题(我没有做同样的事情,但是从第二个域创建第三个域的失败在我脑海中浮现了记忆,然后FileNotFoundException确认了“我的恐惧”)。 / p>

这不是什么好事。证据无法解决。 正如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
  }
}

如果您打算启动第4个域名(依此类推),请继续将证据从一个“truster”传递给另一个“受托人”:

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();
  }
}

希望这是问题。