我遇到以下情况......
1) 在应用程序中创建域。
2) 我们通过DoCallBack程序集加载到其中Assembly.Load(...)
3) 我们从主域中获取先前创建的程序集,例如,显示它们的名称。
4) 我们查看主域中有哪些程序集,更具体地说,这个程序集出现在那里,我们将其上传到另一个域。
也就是说,当将程序集加载到另一个域时,如果您调用该方法GetAssemblies,加载的程序集也会出现在主域中,它们不仅会传输到那里,还会被复制——它们可以在两个域中使用。
如果你循环这个过程并观察内存,你可以看到它在增长,这意味着程序集每次都被加载到内存中。
最大的问题是为什么?如何摆脱将程序集移动到主域?这甚至不是内存问题,而是主域持有对程序集的引用并且不允许删除它的事实,例如。而且您需要以某种方式提取信息。
class Program
{
static void Main ( string [ ] args )
{
var appDomain = AppDomain.CreateDomain("TestDomain");
appDomain.DoCallBack(LoadModule);
var assembly = appDomain.GetAssemblies().Single( t => t.GetName().Name == "TestModule" );
foreach ( var assembly1 in AppDomain.CurrentDomain.GetAssemblies() )
{
Console.WriteLine( assembly1.FullName );
}
}
private static void LoadModule()
{
Assembly.Load( "TestModule" );
}
}
有两种可能性可以跨应用程序域边界传递对象:
System.MarshalByRefObject. 在这种情况下,对代理对象的所有方法调用都会自动重定向到拥有原始对象的应用程序域。在这种情况下,类
System.AppDomain继承自System.MarshalByRefObject而类System.Reflection.Assembly不继承。也就是说,appDomain.GetAssemblies()你的代码中的调用会被重定向到一个额外的应用域,之后它的工作结果 (Assembly[]) 需要被转移到主应用域:在额外域中序列化,在主域中反序列化。将Assembly对象转移到主应用程序域会导致程序集加载到其中。为避免将程序集加载到主域中,请勿将需要加载程序集才能反序列化的对象传递到主域中。就像
System.Reflection.Assembly表示程序集System.Type的对象,表示程序集中任何类型的对象,程序集中任何类型的实例。例如,可以在附加应用程序域中检索程序集名称,并且只能将字符串传递给主应用程序域: