簡體   English   中英

卸載AppDomain

[英]Unloading AppDomain

有沒有一種方法可以卸載父AppDomain?
我正在嘗試在新的AppDomain中加載程序集的其他版本,但是它一直從父域中加載該版本。 當我在新的AppDomain中加載程序集時,我正在顯示正確的路徑。
也許還有另一種方法可以做到這一點?

提前致謝。
編輯

AppDomain MailChimpDomain = AppDomain.CreateDomain("MailChimpDomain");
string path = AppDomain.CurrentDomain.BaseDirectory + "ServiceStack_V3\\ServiceStack.Text.dll";
MailChimpDomain.Load(AssemblyName.GetAssemblyName(path));



EDIT2
代碼2:

var MailDom = AppDomain.CreateDomain("MailChimpDomain");
            MailDom.AssemblyLoad += MailDom_AssemblyLoad;
            MailDom.AssemblyResolve += new ResolveEventHandler(MailDom_AssemblyResolve);
            MailDom.DoCallBack(() =>
            {

                string name = @"ServiceStack.Text.dll";
                var assembly = AppDomain.CurrentDomain.Load(name);
                string name2 = @"MailChimp.dll";
                var assembly2 = AppDomain.CurrentDomain.Load(name2);

                //mailChimp object with API key found in mailChimp profile
                MailChimp.MailChimpManager mc = new MailChimp.MailChimpManager("111111111111222f984b9b1288ddf6f0-us1");
                //After this line there are both versions of ServiceStack.Text Assembly
                MailChimp.Helper.EmailParameter em = new MailChimp.Helper.EmailParameter();
                em.Email = strEmailTo;

                //Creating email parameters
                string CampaignName = "Digest for " + strEmailTo + " " + DateTime.Now.ToShortDateString();
                MailChimp.Campaigns.CampaignCreateOptions opt = new MailChimp.Campaigns.CampaignCreateOptions();
                opt.ListId = "l338dh";
                opt.Subject = strSubject;
                opt.FromEmail = strEmailFrom;
                opt.FromName = strNameFrom;
                opt.Title = CampaignName;

                //creating email content
                MailChimp.Campaigns.CampaignCreateContent content = new MailChimp.Campaigns.CampaignCreateContent();
                content.HTML = strEmailContent;

                //Creating new email and sending it
                MailChimp.Campaigns.CampaignFilter par = null;
                MailChimp.Campaigns.CampaignSegmentOptions SegOpt = null;
                MailChimp.Campaigns.CampaignTypeOptions typeOpt = null;

                mc.CreateCampaign("regular", opt, content, SegOpt, typeOpt);
                MailChimp.Campaigns.CampaignListResult camp2 = mc.GetCampaigns(par, 0, 5, "create_time", "DESC");
                foreach (var item in camp2.Data)
                {
                    if (item.Title == CampaignName)
                    {
                        mc.SendCampaign(item.Id);
                        break;
                    }
                }

            });
static Assembly MailDom_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            byte[] rawAssembly = File.ReadAllBytes(Path.Combine(path, args.Name));
            return Assembly.Load(rawAssembly);
        }

您的代碼實際執行的操作是將程序集加載到您的父域中。 如果要將程序集加載到子域中,則必須從子域中進行。 這是種雞蛋問題,因為父程序集(將子程序集加載到子域中)也必須加載到子域中才能執行。

假設您有一個名為MyAssembly.dll的控制台應用程序和程序集的簡單示例,則可以這樣完成:

static void Main(string[] args) {
  var domain = AppDomain.CreateDomain("MailChimpDomain");
  domain.AssemblyResolve +=new ResolveEventHandler(domain_AssemblyResolve);
  domain.DoCallBack(() => {
    string path = @"MyAssembly.dll";
    var assembly = AppDomain.CurrentDomain.Load(path);

    // to do something with the assembly
    var type = assembly.GetType("MailChimp.MailChimpManager");
    var ctor = type.GetConstructor(new[] { typeof(string) });
    var mc = ctor.Invoke(new object[] { "111111111111222f984b9b1288ddf6f0" });        
  });
}

static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) {
  byte[] rawAssembly = File.ReadAllBytes(Path.Combine(@"c:\MyAssemblyPath", args.Name));
  return Assembly.Load(rawAssembly);
}

在這種情況下,子域具有與父域相同的根目錄來解析程序集(因此,它可以執行加載“ MyAssembly.dll”的代碼)。

如果使用反射的代碼長於此長度,則可以考慮使用引導程序。 IE即會創建一個名為MyBootstrapper.dll的新庫,您將直接從MyBootstrapper.dll中引用所需的ServiceStack.Text.dll和MailChimp.dll版本,並會創建bootstrap類-將其稱為Bootstrapper ,它將是靜態的,將有一個名為Run公共靜態方法,該方法會做臟工作。

然后在DoCallBack()方法中,您將改為調用此引導程序。

string path = @"MyBootstrapper.dll";
var assembly = AppDomain.CurrentDomain.Load(path);

// to do something with the assembly
var type = assembly.GetType("MyBootstrapper.Bootstrapper");
var method = type.GetMethod("Run", BindingFlags.Static);
method.Invoke(null, null);
// or if the Run method has one parameter of "string" type
var method = type.GetMethod("Run", BindingFlags.Static, Type.DefaultBinder, new[] { typeof(string) }, null);
method.Invoke(null, new object[] { "Parameter to run" });

不可以,您不能卸載默認AppDomain或默認AppDomain中加載的任何程序集。

但是,您可以在兩個子域中加載兩個版本的ServiceStack程序集。 您應該能夠卸載其中任何一個。 但是,使用這些域中的類型可能比平時更困難。 您必須通過遠程處理來實現。

考慮到由此帶來的開銷,您應該考慮僅使用該程序集的一個版本(即使這意味着要適應應用程序的一部分,即在默認域中運行的一部分)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM