多个 .NET AppDomain 的代码示例

Posted

技术标签:

【中文标题】多个 .NET AppDomain 的代码示例【英文标题】:Code example of multiple .NET AppDomains 【发布时间】:2010-03-03 03:42:16 【问题描述】:

来自What is a .NET Application Domain?:

您可以在单个进程中运行多个应用程序域,并具有与单独进程相同的隔离级别,但不会产生进行跨进程调用或在进程之间切换的额外开销。

我想更多地了解如何/为什么在他们的应用程序中实际使用多个 AppDomain。谁能提供一个实际代码sn-ps的例子吗?

【问题讨论】:

【参考方案1】:

阅读 MSDN 实际上提供了一些很好的信息。

http://msdn.microsoft.com/en-us/library/system.appdomain.aspx

--丹

【讨论】:

【参考方案2】:

我在以下上下文中使用了它(我现在手头没有代码可以发布)

创建一个新的 AppDomain(例如 appDomainX) 使用此新域创建对象的新实例 新对象(位于新对象中)加载了一堆程序集 反思它们以收集一些指标 获取生成的结果 卸载 appDomainX

这样做的好处是您可以卸载加载到新创建的 AppDomain 中的程序集。如果你在你的主 AppDomain 上一遍又一遍地加载更多的程序集,你的 AppDomain 将会增长得惊人。创建一个单独的 AppDomain 允许您在每次检查后卸载,从而卸载加载到该域的所有程序集,因此主 AppDomain 保持干净。

【讨论】:

【参考方案3】:

我开发了一个(主要是)C++ 软件,它允许用户编写脚本以使用 C# 或 VB.NET 自动化应用程序。该应用程序还有一些用 C# 编写的组件。它使用一个 AppDomain 用于程序组件,另一个用于沙箱脚本。

脚本的原始实现为每个脚本创建了一个 AppDomain,但事实证明这太慢了,并且妨碍了一些有用的脚本行为,因此我们为脚本引擎使用了一个永久的 AppDomain。

【讨论】:

【参考方案4】:

您可能希望使用一个来模拟 IIS 的处理。您需要一个长时间运行的进程来泄漏内存。您可以跟踪 AD 上已处理的请求数量以及一个达到阈值的请求,然后启动一个新请求。当旧的完成所有处理后,将其卸载并让 CLR 清理一些应用垃圾。

不要问我是怎么知道的。 :)

如果您想在不同的安全上下文中运行代码,您也可以这样做。

【讨论】:

【参考方案5】:

.NET 应用程序在其(单个)进程中创建多个 AppDomain 实例的一个非常有用的场景是管理静态变量的范围概念上相关的对象实例的集合。

例如,考虑一个数据库应用程序,其中 90% 的代码管理一组相互关联的 .NET 对象,这些对象包括所有属于的各种表、行和其他视图或数据实体到同一个***数据库。在为数据库本身编写代码时,最好让这个对象图中的每个子实例都是自给自足的,这意味着每个对象单独携带(通过包含)足够的信息来确定它需要关联的任何/所有上下文到数据库的其余部分,而不需要任何外部参考。这允许您传递任何类型的次要实体,而不必担心它可能在内部需要什么额外的上下文。

这种便利的代价是整个应用程序中的每个次要子对象都携带它所需的上下文作为内部字段。如果应用还需要支持多个数据库,例如允许在数据库之间进行比较、导入或导出操作(例如,您的代码的其他 10%),那么每个对象的上下文必须包含直接或间接区分它最终属于哪个数据库的信息。

这些额外的信息会导致内存膨胀,尤其是在更多的低级实例中,并且对于单个给定的“流行”数据库,根据定义,这些承载的大部分上下文将是重复的。

AppDomain 救援... 相反,您的代码的数据库部分可以与每个数据库的不同 AppDomain 相关联。由于静态变量的范围为AppDomain,因此您可以将有关数据库的***信息与AppDomain 相关联,并且每个次要实例都会固有地知道它属于哪个数据库,或者相对于AppDomain.CurrentDomain 静态属性,或者通过简单地引用您定义的静态字段、属性和方法,所有这些都没有任何额外的每个实例字段。

请注意,数据库间(那 10% 部分)代码一次只能引用一个数据库。在此类操作期间,必须明确(以传统方式)引用任何其他数据库。然而,对于大部分代码,这种技术可能会消除部署在所有这些上下文字段中的数百万个对象引用。如果你反对全局单例的想法,请注意AppDomain.CurrentDomain 已经存在于你的 .NET 代码中——所以为什么不好好利用它!

【讨论】:

以上是关于多个 .NET AppDomain 的代码示例的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain 是不是等同于 .NET 代码的进程?

如何识别代码是在 ASP.Net 还是常规 AppDomain 下运行 [重复]

在 .NET Framework 4.0 的 AppDomain 中运行 codeCom 代码

将多个程序集版本加载到多个 AppDomain 中

.Net AppDomain详解

AppDomain 地址空间