将程序集加载到一个新的应用程序域,但不是CurrentDomain
问题描述:
所以我的问题围绕节省内存。将程序集加载到一个新的应用程序域,但不是CurrentDomain
实质上,我需要将程序集加载到主/当前域以外的单独应用程序域中,检查该程序集中的类型,然后在完成时卸载新的域。
目前我的解决方案如下:
AppDomain NewDomain = AppDomain.CreateDomain("newdomain");
foreach(string path in dllPaths) //string list of dll paths
{
byte[] dllBytes = File.ReadAllBytes(dll);
NewDomain.Load(dllBytes); //offending line
}
DoStuffWithNewDomain();
AppDomain.Unload(NewDomain);
的NewDomain.Load线似乎装配加载到新的领域,但也到我的程序的当前域。
我用这个链接作为参考 - http://www.csharp411.com/how-to-load-a-net-assembly-into-a-separate-appdomain-so-you-can-unload-it/
非常感谢:)
答
正如埃里克建议,你需要使用CreateInstanceAndWrap。这里有一个例子,我在VB中做了一段时间...
Private Function GetCoupler() As IBatchCoupler
Dim CouplerProxy As IBatchCoupler = Nothing
Try
Dim DomainSetupInfo As AppDomainSetup = New AppDomainSetup()
DomainSetupInfo.ConfigurationFile = Path.Combine(mFilePath, "web.config")
DomainSetupInfo.ApplicationBase = Path.Combine(mFilePath, "bin")
DomainSetupInfo.ShadowCopyFiles = "true"
Dim domain As AppDomain = AppDomain.CreateDomain("CoolDomain", AppDomain.CurrentDomain.Evidence, DomainSetupInfo)
'Create remote object in new appDomain via the coupler interface
'to avoid loading the design library into the calling application's primary appDomain
CouplerProxy = domain.CreateInstanceFromAndUnwrap(Path.Combine(DomainSetupInfo.ApplicationBase, "Design.dll"), "BigApplication.Design.BatchCoupler")
Catch ex As Exception
ThisLogger.Error(ex)
End Try
Return CouplerProxy
End Function
答
如前所述,从字节加载程序集只能发生在当前应用程序域。
下面是使用应用程序域上的DoCallBack
方法(http://msdn.microsoft.com/en-us/library/system.appdomain.docallback%28v=vs.110%29.aspx)上下文切换以使目标应用程序域成为当前应用程序域的一种方法。
加载程序集后,您可以使用相同的方法检查新应用程序域的程序集和类型,并在卸载它之前根据需要创建实例。
class Program
{
static void Main(string[] args)
{
AppDomain newDomain = AppDomain.CreateDomain("NewDomain");
List<string> dllPaths = new List<string>() { @"c:\dev\taglib-sharp.dll" };
foreach (string dll in dllPaths)
{
AppDomainAsmLoader asmLoad = new AppDomainAsmLoader(File.ReadAllBytes(dll));
newDomain.DoCallBack(new CrossAppDomainDelegate(asmLoad.LoadAsm));
}
newDomain.DoCallBack(new CrossAppDomainDelegate(DoWorkWithAppDomain));
AppDomain.Unload(newDomain);
Console.ReadKey();
}
public static void DoWorkWithAppDomain()
{
Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly asm in asms)
{
Type[] types = asm.GetTypes();
foreach (Type type in types)
{
Console.WriteLine("Found the type: {0}", type.FullName);
}
}
}
[Serializable]
public class AppDomainAsmLoader
{
private byte[] AsmData;
public AppDomainAsmLoader(byte[] data)
{
AsmData = data;
}
public void LoadAsm()
{
Assembly asm = Assembly.Load(AsmData);
}
}
}
我不知道是否有什么关系的文件['AppDomain.Load方法(Byte [])'](http://msdn.microsoft.com/en-us/library/7hcs6az6% 28v = vs.110%29.aspx)表示'这种方法只能用于将程序集加载到当前应用程序域中。 ...要将程序集加载到其他应用程序域中,请使用诸如CreateInstanceAndUnwrap.'之类的方法 – 2014-11-21 22:36:18