代码之家  ›  专栏  ›  技术社区  ›  Brent Arias

制作与域无关的程序集的步骤是什么?

  •  4
  • Brent Arias  · 技术社区  · 15 年前

    …这些步骤是否也可以应用于第三方程序集(可能已经是强名称的程序集)?

    我的问题的上下文应该不重要,但我还是要与大家分享:我正在考虑制作一个日志记录器(或日志包装器),它总是知道目标是什么“日志源”,而不管使用它的程序集是在一个appdomain中,还是分布在多个appdomain中。我认为实现这一点的一种方法是使用一个具有静态“LogSource”属性的域无关程序集。如果在与域无关的程序集中设置了该静态属性,我想所有appdomains都会看到它。

    3 回复  |  直到 15 年前
        1
  •  16
  •   Stefan Dragnev    13 年前

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

    CLR实例决定如何加载程序集是由策略决定的。有几种方法可以显式设置此策略:

    作为域中立加载的程序集将加载到共享域中。应用程序域名在CLRv4中为“EE共享程序集存储库”。这不是一个真正的应用程序域,因为它没有数据,也不能运行任何代码。加载到其中的程序集将在所有其他正在运行的应用程序域中共享其代码。程序集中的字节码将只进行一次JIT编译。但是,程序集中的所有可变数据将在正在运行的域中复制。 应用程序域之间不共享静态字段。 每个应用程序域静态字段将被复制,不同的应用程序域在引用同一静态字段时将在内存中的不同位置进行读写。

    旁白:还有另一种静态字段-RVA statics,它在当前进程中的所有应用程序域之间共享。C++中没有这样的字段,但是它可以用C++或CLI来完成。

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

    • 如果您加载了多个运行基本相同代码的域,您可能希望尽可能多地共享程序集,除非这会严重影响访问静态字段的性能。例如,一个应用程序决定在一个单独的应用程序域中运行自己的部分代码以实现隔离。
    • 如果用不同的代码加载多个域,则只希望共享所有不同程序集可能常用的程序集。这些通常是.NETFramework自己的程序集以及从GAC加载的所有程序集。IIS在运行ASP.NET应用程序时默认采用这种方式。
    • 如果你只使用一个应用程序域,你不应该共享任何东西。常规的GUI应用程序就是这样。

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

    资料来源和进一步阅读:

        2
  •  3
  •   Franci Penov    15 年前

    与域无关的程序集仅跨appdomains共享代码。但是,数据仍然是每个appdomain的。因此,将有一个静态 LogSource

        3
  •  0
  •   Bogdan Mart Staale    9 年前

    实际上,有一种棘手的、没有文档记录的方法可以跨域共享数据,但它会导致运行时错误和整个应用程序崩溃。作者不建议在实际项目中使用它,所以您可以改用MarshalByRef对象来共享日志使用者。

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

    推荐文章