AppDomain Unload 杀父 AppDomain [英] AppDomain Unload killing Parent AppDomain

查看:24
本文介绍了AppDomain Unload 杀父 AppDomain的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法弄清楚我的 AppDomain.Unload(...) 调用.我对我之前的问题中的代码进行了详细解释.事实证明,我正在执行几个显然不需要的步骤.但是,我相当肯定,当 AppDomain 被创建并保存在一个集合中时:

I am having trouble figuring something out about my AppDomain.Unload(...) call. I have a detailed explanation with code from my earlier question. As it turns out, I was performing a couple of steps that apparently, I don't need to. However, I am fairly certain that when an AppDomain is created and then held in a collection:

private static Dictionary<string , AppDomain> HostDomains;

void StartNewDomain(string domainName)
{
    AppDomain domain = AppDomain.CreateDomain(domainName);
    HostDomains[domainName] = domain;
}

...当你完成它时,你必须卸载它:

...when you are done with it, you must unload it:

if (HostDomains.ContainsKey(domainName))
{
    AppDomain.Unload(HostDomains[domainName]);
    HostDomains.Remove(domainName);
}

然后从集合中删除域.

然而,当我卸载域时,整个应用程序都结束了.如果我删除卸载,一切都很好……我们只剩下从集合中删除域.但我担心我的孩子 AppDomain 没有真的卸载了.我猜它最终可能会被垃圾回收,但这并没有让我感到温暖.

When I unload the domain, however, the entire application is ending. If I remove the unload, all is well...and we are simply left with removing the domain from the collection. But I fear that my child AppDomain is not really unloaded. It may eventually get GC'd I guess, but that doesn't give me a warm fuzzy.

子 AppDomain 程序集(Windows 窗体应用程序)通过接口 (IModule) 异步启动,该接口在继承 MarshalByRefObject 的适配器类中引用.我想知道这个对 IModule 的 Start()(插件模块程序集实现的)的引用是否没有正确编组(因为我的实现).因此,当调用 Shutdown() 方法时,整个应用程序就会死亡.我应该让我的 IModule 成为一个抽象类,所以它也应该继承 MBR 吗?不解...

The child AppDomain assembly (a Windows Form application) is started asynchronously via an interface (IModule) that is referenced in my adapter class which inherits MarshalByRefObject. I am wondering if this reference to IModule's Start() (which the plugin module assembly implements) is not marshaling properly (because of my implementation). So, when the Shutdown() method is called, the entire application dies. Should I make my IModule an abstract class instead so it should inherit MBR as well? Puzzled...

查看我的代码后:

// instances the module for access to the module's Start() method
    IModule module = (IModule)domain.CreateInstanceAndUnwrap(
    ModuleManager.Modules[modName].Name, 
    ModuleManager.Modules[modName].EntryPoint.FullName);

...我担心的是,由于 IModule 是一个接口,即使我在子域中创建一个实例,程序集也会泄漏到我的主 AppDomain 中.因此,当我尝试卸载子域时,两个域都被卸载.这是正确的吗?什么可能是提供 Start() & 的最佳解决方案通过 MBR(适配器)对象的 Stop() 方法?

...my fear is that since IModule is an interface, even though I am creating an instance in a child domain, the assembly is leaking into my main AppDomain. Therefore, when I attempt to unload the child domain, both domains are being unloaded. Would this be correct? And what would likely be the best solution to provide Start() & Stop() methods via the MBR (adapter) object?

更新:有关更改,请参阅下面的答案--
好的,没有泄漏——一切都继承了 MBR:

UPDATE: see my answer below for changes --
Okay, there is no leaking -- everything inherits MBR:

  1. Host : MarshalByRefObject -- 在新的 AppDomain 中实例化 ModuleAdapter
  2. ModuleAdapter : MarshalByRefObject -- IModule 接口,接口方法 (Start,Stop)
  3. MyModulePlugin : MarshalByRefObject -- Application.Run(myForm)

我还是做错了吗?我已经尝试了几件事,但它似乎是错误的或不完整的.当我告诉 ModuleAdapter 关闭时,它调用 AppDomain.Unload(AppDomain.CurrentDomain) 并且主机域也停止.我仍然在应用程序退出时遇到一些第一次机会异常.但是表单 (myForm) 已被告知 .Close().

Am I doing something wrong still? I've tried several things and it just seems to be wrong or incomplete. When I tell the ModuleAdapter to shutdown, it calls AppDomain.Unload(AppDomain.CurrentDomain) and the Host domain stops as well. I am still getting some first chance exceptions on the application exit. But the form (myForm) has been told to .Close().

所以,我仍在寻找这样做的正确方法......

So, I am still looking for the correct way of doing this...

推荐答案

正如我所怀疑的,在主域中使用 IModule 接口进行实例化会导致泄漏.为了正确执行此操作:

As I suspected, instancing with the IModule interface in the primary domain causes a leak. In order to do this properly:

AppDomain domain = AppDomain.CreateDomain(domainName);
HostDomains[domainName] = domain;  // put in collection

ModuleAdapter adapter = (ModuleAdapter)domain.CreateInstanceAndUnwrap(asmName , typeName);

其中 ModuleAdapter 继承了 MarshalByRefObject.然后:

where ModuleAdapter inherits MarshalByRefObject. Then:

adapter.Execute(moduleAssembly , moduleType);

在 ModuleAdapter 类中:

Inside the ModuleAdapter class:

public void Execute(string Name, string EntryPoint)
{
    module  = (IModule)AppDomain.CurrentDomain.CreateInstanceAndUnwrap(Name , EntryPoint);
}

我欢迎评论或其他答案以获得更好的方法.

I do welcome comments or additional answers for a better way.

在将实例化到 ModuleAdapter 类之后,我们仍然遇到 AppDomain.Unload 杀死整个应用程序的问题.我想知道这是不是因为在模块插件中我们使用了 Application.Run(myForm) - 然后当我们关闭时我们调用 myForm.Close().显然这会关闭应用程序,所以我想知道 myForm.Close() 是否也卸载"了 AppDomain.

After moving the instancing to the ModuleAdapter class, we are still having the issue with AppDomain.Unload killing the entire application. I was wondering if this is because in the module plugin we are using Application.Run(myForm) - then when we shutdown we call myForm.Close(). Obviously this shuts down the application so I was wondering if the myForm.Close() also 'unloads' the AppDomain.

这篇关于AppDomain Unload 杀父 AppDomain的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆