【问题标题】:Load Assembly into a new app domain but not CurrentDomain将程序集加载到新的应用程序域但不是 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[]) 的文档有关

标签: c# .net .net-assembly remoting appdomain


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      相关资源
      最近更新 更多