...这些步骤也可以应用于第三方议会(可能已经是强名称的)吗?
我的问题的上下文应该不重要,但无论如何我都会分享:我正在考虑制作一个记录器(或日志包装器),它始终知道要定位的“日志源”,无论使用它的程序集是否是在一个应用程序域中,或分布在多个应用程序域中。我认为实现这一目标的一种方法是拥有一个具有静态“LogSource”属性的域中立程序集。如果在与域无关的程序集中设置该静态属性,我认为所有应用程序域都会看到它。
程序集没有以任何特定方式标记为领域中立。您不必给它们一些特定的属性来使它们与域无关。任何程序集都可以由 CLR 加载到共享域或触发程序集加载的域中,具体取决于 CLR 的配置CLR实例那就是加载程序集。
CLR 实例决定如何加载程序集由策略决定。有多种方法可以显式设置此策略:
- set 加载器优化属性 http://msdn.microsoft.com/en-us/library/system.loaderoptimizationattribute.aspx在可执行文件的入口点(通常是 Main)。 CLR 加载程序将在启动可执行文件时应用指定的策略。
- set the AppDomainSetup.Loader优化 http://msdn.microsoft.com/en-us/library/system.appdomainsetup.loaderoptimization.aspx从托管代码创建新的应用程序域时的属性。
-
CorBindToRuntimeEx http://msdn.microsoft.com/en-us/library/99sz37yh.aspx- 当从非托管代码启动 CLR 时,此函数允许您指定启动标志 http://msdn.microsoft.com/en-us/library/ms231027.aspx,其中一些控制加载器优化。
作为域中立加载的程序集将被加载到共享域中。应用域名是 CLRv4 中的“EE Shared Assembly Repository”。这不是真正的应用程序域,因为它没有数据并且无法运行任何代码。加载到其中的程序集将在所有其他正在运行的应用程序域之间共享其代码。程序集中的字节代码将仅进行一次 JIT 编译。然而,程序集中的所有可变数据都将在运行域之间复制。静态字段不在应用程序域之间共享。每个应用程序域的静态字段将被重复,并且当引用相同的静态字段时,不同的应用程序域将在内存中的不同位置读取和写入。
另外:还有另一种静态字段 - RVA 静态字段,它在当前进程中的所有应用程序域之间共享。无法在 C# 中声明这样的字段,但可以在 C++/CLI 中完成。
使用域中立程序集需要权衡。访问静态字段的速度较慢。由于它们仅进行一次 JIT 处理,但可以访问每个应用程序域静态字段的多个实例,因此对静态字段的任何访问都会经过额外的间接访问。当程序集直接加载到运行域中时,静态字段的地址可以直接嵌入到 JIT 代码中。但是,当编译到共享程序集中的代码尝试访问静态字段时,它必须首先加载当前域的上下文,然后在其中查找该域的静态字段地址。
决定是将程序集加载到共享域还是运行域取决于您的用例,更具体地说,您要创建多少个应用程序域以及要加载到其中的核心类型。
- 如果加载运行本质上相同代码的多个域,您会希望尽可能多地共享程序集,除非它会严重损害访问静态字段的性能。一个示例是,为了隔离,应用程序决定在单独的应用程序域中运行自己的部分代码。
- 如果您使用不同的代码加载多个域,则您只想共享所有不同程序集可能常用的程序集。这些通常是 .NET Framework 自己的程序集以及从 GAC 加载的所有程序集。运行 ASP.NET 应用程序时,IIS 默认以这种方式工作。
- 如果您只使用一个应用程序域,则不应共享任何内容。常规的 GUI 应用程序就是这样。
注意:mscorlib 始终加载到共享域中。
来源和进一步阅读:
- 应用程序域和程序集 http://msdn.microsoft.com/en-us/library/43wc4hhs.aspx
- 领域中立的程序集 http://blogs.msdn.com/b/junfeng/archive/2004/08/05/208375.aspx
-
Essential .NET,第 1 卷,Addison Wesley http://www.amazon.ca/Essential-NET-Volume-Language-Runtime/dp/0201734117;第 8 章“AppDomains 和代码管理”
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)