制作域中立程序集的步骤是什么?

问题描述:

......并且这些步骤是否也可以应用到第三方程序集(可能已经是强名称)?制作域中立程序集的步骤是什么?

我的问题的背景应该不重要,但无论如何我都会分享:我正在考虑制作一个记录器(或日志包装器),它总是知道目标是什么“日志源”,无论使用它的程序集位于一个AppDomain中,或分布在多个AppDomain中。我认为实现这一目标的一种方式是使用静态“LogSource”属性来创建一个与域无关的程序集。如果这个静态属性是在一个域中立的程序集中设置的,我认为所有的appdomains都会看到它。

组件未以任何特定方式标记为域中立。你不必给他们一些特定的属性,使他们的领域中立。任何程序集都可以由CLR加载到共享域或触发程序集加载的域中,具体取决于加载程序集的CLR实例的配置。

CLR实例如何决定加载程序集是由策略决定的。有几种方法明确地设置此策略:

作为域中立加载的程序集将被加载到共享域中。应用程序域名是CLRv4中的“EE Shared Assembly Repository”。这不是一个真正的应用程序域,因为它没有数据并且不能运行任何代码。装入其中的程序集将在所有其他正在运行的应用程序域中共享其代码。程序集中的字节码将仅被JIT编译一次。然而,程序集中的所有可变数据将在正在运行的域中复制。 静态字段不在应用程序域之间共享。每个应用程序域的静态字段将被复制,并且当引用相同的静态字段时,不同的应用程序域将在内存的不同位置读取和写入。

除此之外:还有另一种静态字段 - RVA静态字段,它们在当前进程中的所有应用程序域之间共享。没有办法在C#中声明这样的字段,但可以在C++/CLI中完成。

在使用域中立程序集时有一个权衡。 访问静态字段速度较慢。由于它们只被打乱一次,但可以访问每个应用程序域静态字段的多个实例,因此对静态字段的任何访问都会经历一次额外的间接访问。当程序集直接加载到正在运行的域中时,静态字段的地址可以直接嵌入到JIT代码中。但是,当编译到共享程序集的代码尝试访问静态字段时,它必须首先加载当前域的上下文,然后在其中找到该域的静态字段地址。

是否组件加载到共享的域到正在运行的域的决定取决于你的使用情况,更具体地说你的应用程序有多少域创建和你加载到它什么样的核心。

  • 如果您加载了多个运行基本相同的代码的域,您希望尽可能共享程序集,除非它明显伤害了访问静态字段的性能。一个示例是一个应用程序,为了隔离的目的决定在单独的应用程序域中运行其自己代码的一部分。
  • 如果您加载不同的代码多个域,你会想分享只有那些可能常用的所有不同的组件装配。这些通常是.NET Framework自己的程序集和从GAC加载的所有程序集。运行ASP.NET应用程序时,IIS默认以这种方式工作。
  • 如果您只使用一个应用程序域,则不应该共享任何内容。常规的GUI应用程序就是这样。

注意:mscorlib总是加载到共享域中。

来源和进一步阅读:

+1

有没有办法将类库程序集标记为域中立。 LoaderOptimizationAttribute只能在Main方法上设置。类库没有。 – 2013-04-20 18:24:11

+0

非常全面的答案!如果可以的话,我会让你喜欢两次。 @AbhijeetPatel这是一个很好的问题。我遇到了同样的问题,我无法在类库中指定此属性。 – Brain2000 2014-03-13 16:34:06

域中立程序集只共享应用程序域中的代码。但是,数据仍然是每个appdomain。因此,每个域都会有一个您的静态LogSource属性的副本。

+0

但是,你如何创建一个域中立的程序集?并且第三方(可能是强名)组件也可以转换吗? – 2010-06-17 02:56:23

+0

您在汇编构建时没有做任何具体的工作。 CLR根据主机和应用程序策略在加载时决定程序集是否可以加载为域中立。 – 2010-06-17 03:13:57

+0

@Franci:我看到一个不同的故事(http://www.drdobbs.com/184405853;jsessionid=VQ1FBYMTHDGU5QE1GHRSKH4ATMY32JVN)。看来我只能使主程序与域无关,并且必须使用LoaderOptimizationAttribute进行修饰。我是否回答了我自己的问题,或者.net 3.5或4.0改变了故事? – 2010-06-17 23:20:14

实际上有一个棘手的,未公开的方式来跨域共享数据,但它可能会导致运行时错误和整个应用程序崩溃。作者不建议在实际项目中使用它,因此您可以使用MarshalByRef对象来共享日志消费者。 但是你也可以使用这个技巧分享它。

http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx