在AppDomain卸载后,程序集无法卸载吗? [英] Assemblies not unloading after AppDomain unload?

查看:211
本文介绍了在AppDomain卸载后,程序集无法卸载吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AppDomain加载程序集,然后将其卸载。

I'm using an AppDomain in order to load assemblies and then unload them.

但是,我遇到了一个非常棘手的问题。卸载AppDomain后-我仍然可以在Process Explorer中看到某些程序集已多次加载!
为什么加载的程序集有剩余的?不是AppDomain.Unload释放了AppDomain的所有已加载内存吗?

However, I'm having a very strage problem. After the AppDomain is unloaded - I can still see in process explorer that some assemblies are loaded multiple times! Why are there remainders of the loaded assemblies? Doesn't an AppDomain.Unload frees all the AppDomain's loaded memory?

您可以在所附的图片中看到:

You can see in the attached image:

AppDomain总数为3(我在该流程的生命周期中创建了3个AppDomain)

Total AppDomains are 3 (I created 3 AppDomains in the process's life-cycle)

AppDomains:1(目前仅存在1个AppDomain)

AppDomains: 1 (Currently only 1 AppDomain exists)

由于某种原因,如下面的DLL加载部分所示-程序集已多次加载到进程中。

And for some reason, as you can see in the loaded DLL section bellow - Assemblies are loaded multiple times into the process..

代码:

AppDomain fetcherDomain = AppDomain.CreateDomain("StatusFetcher");
try
{
    var fetcher = (LocalStatusFetcher)fetcherDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().CodeBase, typeof(LocalStatusFetcher).FullName);
    //doing some other stuff that is not interesting...
}
finally
{
    AppDomain.Unload(fetcherDomain);
}

是的,LocalStatusFetcher确实继承了MarshalByRefObject ...

And yes, LocalStatusFetcher does inherit MarshalByRefObject...

推荐答案

很有可能将要加载到外部应用程序域中的程序集放到当前程序集中。有 ton 种可能的方式,但是您遇到的问题尤其是将 Assembly.GetExecutingAssembly()。CodeBase 传递给 CreateInstanceFromAndUnwrap 方法。调用 Assembly.GetExecutingAssembly()会将当前正在执行的程序集加载到 current 应用程序域中,并传递 .CodeBase
CreateInstanceFromAndUnwrap 属性将尝试先将目标程序集(位于应用程序路径或GAC中)加载到目标域中实例化您的目标代理。目前,除了可能出现的出血问题外,我看不到这段代码有什么问题。

There's a very high possibility that the assemblies you're loading into the foreign application domain are being bled into the current one. There are tons of ways that this can happen, but your problem in particular is passing Assembly.GetExecutingAssembly().CodeBase to the CreateInstanceFromAndUnwrap method. A call to Assembly.GetExecutingAssembly() loads the currently executing assembly into the current app domain, and passing the .CodeBase property to CreateInstanceFromAndUnwrap will attempt to load the target assembly (located in the application path or in the GAC) into the target domain before instantiating your target proxy. Currently, I see nothing wrong with this code other than the possible bleeding issue.

如果您有多个应用程序域,那么您将在LoadFrom中看到程序集的多个副本。上下文,因为在AppDomains之间共享的 only 程序集是mscorlib.dll。除非我误解了您的问题,否则我认为您看到的是正常现象。

If you have multiple application domains then you'll see multiple copies of the assembly in the LoadFrom context because the only assembly that is shared across AppDomains is mscorlib.dll. Unless I'm misunderstanding your question I think what you're seeing is normal.

这篇关于在AppDomain卸载后,程序集无法卸载吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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