【发布时间】:2011-02-08 13:21:44
【问题描述】:
我需要创建一个自定义应用程序域来解决 .NET 运行时 default behavior 中的错误。我在网上看到的示例代码都没有帮助,因为我不知道将它放在哪里,或者它需要在我的 Main() 方法中替换什么。
【问题讨论】:
我需要创建一个自定义应用程序域来解决 .NET 运行时 default behavior 中的错误。我在网上看到的示例代码都没有帮助,因为我不知道将它放在哪里,或者它需要在我的 Main() 方法中替换什么。
【问题讨论】:
可能应该注意的是,创建AppDomains 只是为了解决可以用常量字符串修复的问题,这可能是错误的做法。如果您尝试做与您记下的链接相同的事情,您可以这样做:
var configFile = Assembly.GetExecutingAssembly().Location + ".config";
if (!File.Exists(configFile))
throw new Exception("do your worst!");
递归入口点 :o)
static void Main(string[] args)
{
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
{
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
var currentAssembly = Assembly.GetExecutingAssembly();
var otherDomain = AppDomain.CreateDomain("other domain");
var ret = otherDomain.ExecuteAssemblyByName(currentAssembly.FullName, args);
Environment.ExitCode = ret;
return;
}
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("Hello");
}
使用非静态辅助入口点和 MarshalByRefObject 的快速示例...
class Program
{
static AppDomain otherDomain;
static void Main(string[] args)
{
otherDomain = AppDomain.CreateDomain("other domain");
var otherType = typeof(OtherProgram);
var obj = otherDomain.CreateInstanceAndUnwrap(
otherType.Assembly.FullName,
otherType.FullName) as OtherProgram;
args = new[] { "hello", "world" };
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
obj.Main(args);
}
}
public class OtherProgram : MarshalByRefObject
{
public void Main(string[] args)
{
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
foreach (var item in args)
Console.WriteLine(item);
}
}
【讨论】:
AppDomain 对象上还有一个.ExecuteAssembly(...) 方法,您可以提供指向另一个包含入口点的程序集的路径。这可能会带来更简洁的设计,但至少需要两个组件。
mscoree.tlb 的情况下弄清楚如何做到这一点。
你需要:
1) 创建 AppDomainSetup 对象的实例,并使用您想要的域设置信息填充它
2) 使用 AppDomain.CreateDoman 方法创建新域。带有配置参数的 AppDomainSetup 实例被传递给 CreateDomain 方法。
3) 使用域对象上的 CreateInstanceAndUnwrap 方法在新域中创建对象的实例。此方法获取您要创建的对象的类型名并返回一个远程代理,您可以在您的主域中使用该代理与在新域中创建的对象进行通信
完成这 3 个步骤后,您可以通过代理调用其他域中的方法。您也可以在完成后卸载域并重新加载它。
MSDN 帮助中的这个topic 有非常详细的示例说明您需要什么
【讨论】:
MarshalByRefObject,否则它只会尝试将副本序列化回原始 AppDomain。