创建二级AppDomain挂起
本文关键字:二级 AppDomain 挂起 创建 | 更新日期: 2023-09-27 17:51:10
我有两个主要方法的程序集。
- 第一个执行另一个。
- 第二个程序集在新的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上验证过了。
为什么?我怎样才能克服这个问题?
==EDIT==
(在。net上测试)我越来越糊涂了。
我对PathToSecondAssembly
有问题。当二进制文件在保存文件夹中时,一切似乎都很好(在。net 4.0上测试,但我假设mono也是如此)。
当我使用相对路径或不同目录的路径时,结果如下:
- 在调试在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),但是异常出现了。
我真的不知道为什么。某种权限问题?如何克服这种情况?
我曾经有过类似的问题(我没有做同样的事情,但是从第二个域创建第三个域的失败在我的脑海中出现了记忆,然后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();
}
}
希望这是问题所在。