将程序集加载到新的应用程序域但不是 CurrentDomain
Posted
技术标签:
【中文标题】将程序集加载到新的应用程序域但不是 CurrentDomain【英文标题】:Load Assembly into a new app domain but not CurrentDomain 【发布时间】:2014-11-21 22:22:36 【问题描述】:所以我的问题围绕着节省内存。
本质上,我需要将程序集加载到主/当前域之外的单独应用程序域中,检查该程序集中的类型,然后在完成后卸载新域。
目前我的解决方案如下:
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/
非常感谢:)
【问题讨论】:
我想知道它是否与声明This method should be used only to load an assembly into the current application domain. ... To load assemblies into other application domains, use a method such as CreateInstanceAndUnwrap.
的 AppDomain.Load Method (Byte[])
的文档有关
【参考方案1】:
如前所述,从字节加载程序集仅适用于当前应用程序域。
这是上下文切换的一种方法,使您的目标应用程序域成为当前应用程序域,使用应用程序域 (http://msdn.microsoft.com/en-us/library/system.appdomain.docallback%28v=vs.110%29.aspx) 上的 DoCallBack
方法。
加载程序集后,您可以使用相同的方法检查新应用程序域的程序集和类型,并在卸载之前根据需要创建实例。
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);
【讨论】:
【参考方案2】:正如 Erik 建议的那样,您需要使用 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
【讨论】:
以上是关于将程序集加载到新的应用程序域但不是 CurrentDomain的主要内容,如果未能解决你的问题,请参考以下文章
无法将存档的 NSMutableArray 加载到新的 NSMutableArray
如何将变量保存到新的文本文件中,以便下次程序运行时加载这些变量?
无法在新的 AppDomain 中创建 UserControl
将datagridview中的数据集存储到新的访问数据库文件c#