是否可以避免将一些程序集加载到“AppDomain”中?
Posted
技术标签:
【中文标题】是否可以避免将一些程序集加载到“AppDomain”中?【英文标题】:Is it possible to avoid to load some assembly loading into the `AppDomain`? 【发布时间】:2016-10-26 18:43:29 【问题描述】:我需要将SomeMixedAssembly.dll
加载到附加域(即它不是主域)并在完成任务后卸载该域。 SomeMixedAssembly.dll
还加载了工作所必需的 SomeMixedAssembly_2.dll
。两个程序集都是混合的,不是我写的。这不是问题,但问题是SomeMixedAssembly.dll
也将SomeMixedAssembly_2.dll
加载到主域。
是否可以避免将一些程序集加载到主AppDomain
?
【问题讨论】:
您需要创建自己的代理来处理默认域和您创建的域之间的通信。然后将该代理加载到其自己的域中,并且是SomeMixedAssembly
中定义的类型的包装器。不要直接通过代理泄漏SomeMixedAssembly
中的任何类型。这应该会阻止 SomeMixedAssembly
加载到默认域及其依赖项中。
为了澄清 Igors 的评论,程序集没有将自身加载到主域中。 您是通过将对象从辅助域复制到主域来强制将类型加载到那里。
我知道AppDomain.AssemblyResolve
,我使用代理。我的“HelloWorld”示例在这里(git 存储库):bitbucket.org/Andrey-Bushman/acadcui/wiki/HomeSomeMixedAssembly.dll
是 AcCUI.dll
,SomeMixedAssembly_2.dll
是 AcDbMgd.dll
。
我想“混合”这个词在这里适用。 AppDomain 是一个纯托管的概念,它们只隔离托管对象。混合模式程序集中本机代码分配的任何内存都不是隔离的。不可能。本机代码的隔离边界是一个进程。
@HansPassant,这是否意味着任何混合程序集总是将被加载到主AppDomain
也 ?
【参考方案1】:
是的,您可以干预程序集加载过程,例如使用AppDomain.AssemblyResolve 事件处理程序。但是程序集通常会按需加载延迟,您不能只是不加载它们并期望您的程序能够工作。根据定义,在另一个 AppDomain 中加载的程序集不能自动作为原始程序集工作。
但如果您想从不寻常的地方加载程序集、检查一些先决条件或搜索错误,这种干预可能会很有用。
【讨论】:
我知道并使用它,但它对我没有帮助。你可以在这里看到我的“Hello World”:bitbucket.org/Andrey-Bushman/acadcui/wiki/Home 我从您的代码中看到的唯一可能原因:包含 Bushman.AcadCUI.Section 类的程序集可能对 Acdbmgd.dll 有直接或链式引用。尝试在“ISection section =”行设置断点并检查已加载的程序集。然后退出并再次检查。如果我的猜测是正确的,则在此步骤中加载了不需要的程序集。然后,IlSpy 或 Reflector 可以帮助您。 发生在Program.cs
文件的第83行。
真的吗?在第 83 行,您在 taskDomain 中调用 DoWork。这是否意味着在第 39 行已经加载了不需要的程序集?
我没有注意到你的 exe 中声明了 Section 类,所以我纠正了我的猜测:最有趣的地方是 Section.cs 的第 61-68 行。可能不需要的加载是 CustomizationSection 构造函数代码的结果。以上是关于是否可以避免将一些程序集加载到“AppDomain”中?的主要内容,如果未能解决你的问题,请参考以下文章
在不知道类型的情况下将程序集从文件加载到自定义 AppDomain