制作域中立程序集的步骤是什么? [英] What are the steps for making domain-neutral assemblies?

查看:20
本文介绍了制作域中立程序集的步骤是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

...这些步骤是否也可以应用于第 3 方程序集(可能已经具有强名称)?

...and can those steps also be applied to a 3rd party assembly (that might already be strong-named)?

我的问题的上下文不应该很重要,但无论如何我都会分享:我正在考虑制作一个记录器(或日志包装器),它始终知道要定位的日志源",无论程序集是否在一个应用程序域中使用它,或分布在多个应用程序域中.我认为实现这一目标的一种方法是拥有一个具有静态LogSource"属性的域中立程序集.如果在域中立程序集中设置该静态属性,我认为所有应用程序域都会看到它.

The context for my question should not be important, but I'll share anyway: I'm thinking of making a logger (or log-wrapper) that always knows what "log source" to target, regardless of whether the assemblies using it are in one appdomain, or spread across several appdomains. I think one way to achieve that, is to have a domain-neutral assembly with a static "LogSource" property. If that static property is set in a domain-neutral assembly, I think all appdomains will see it.

推荐答案

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

Assemblies aren't marked as domain-neutral in any specific way. You don't have to give them some specific attribute to make them domain-neutral. Any assembly can be loaded by the CLR either into the shared domain or the domain that triggered the assembly load depending on the configuration of the CLR instance that is loading the assembly.

CLR 实例如何决定加载程序集由策略决定.有多种方法可以明确设置此政策:

How the CLR instance decides to load an assembly is dictated by policy. There are several ways to explicitly set this policy:

  • 在可执行文件的入口点(通常是 Main)上设置 LoaderOptimizationAttribute.CLR 加载程序将在启动可执行文件时应用指定的策略.
  • 在从托管代码.
  • CorBindToRuntimeEx - 从非托管代码启动 CLR 时,此函数允许您指定 启动标志,其中一些控制加载器优化.
  • set LoaderOptimizationAttribute on your executable's entry point (usually Main). The CLR loader will apply the specified policy when starting the executable.
  • set the AppDomainSetup.LoaderOptimization property when creating a new app domain from managed code.
  • CorBindToRuntimeEx - when starting the CLR from unmanaged code, this function allows you to specify start-up flags, some of which control the loader optimization.

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

An assembly loaded as domain-neutral will be loaded into the shared domain. The app domain name is "EE Shared Assembly Repository" in CLRv4. That's not a real app domain, because it has no data and can't run any code. Assemblies loaded into it will share its code among all other running app domains. The byte code in the assembly will be JIT-compiled only once. All mutable data in the assembly, however, will be duplicated among the running domains. Static fields are not shared between app domains. Per-app domain static fields will be duplicated and different app domains will read and write in different places in the memory when referring to the same static field.

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

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

There is a trade-off in using domain-neutral assemblies. Access to static fields is slower. Since they're JIT-ted only once, but may access multiple instances of a per-app domain static field, any access to a static field goes through an additional indirection. When an assembly is loaded straight into the running domain, the address of the static field can be directly embedded into the JIT-ted code. However, when code compiled into the shared assembly tries to access a static field, it must first load the current domain's context and then find in it the static field address for this domain.

是将程序集加载到共享域还是运行域的决定取决于您的用例,更具体地说,您将创建多少个应用程序域以及您将加载到其中的核心类型.

The decision whether to load an assembly into the shared domain or into the running domain depends on your use case, more specifically how many app domains you'd create and what sort of core you'd load into it.

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

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

来源和进一步阅读:

  • Application Domains and Assemblies
  • Domain Neutral Assemblies
  • Essential .NET, Volume 1, Addison Wesley; chapter 8 "AppDomains and Code Management"

这篇关于制作域中立程序集的步骤是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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