来自What is a .NET Application Domain?:
您可以在单个进程中运行多个应用程序域,这些应用程序域具有与单独进程中相同的隔离级别,但不会产生进行跨进程调用或在进程之间切换的额外开销。
我想更多地了解如何/为什么在他们的应用程序中实际使用多个AppDomain。任何人都可以提供实际代码片段的示例吗?
答案 0 :(得分:5)
答案 1 :(得分:3)
我在以下上下文中使用了这个(现在没有代码方便我发布)
这样做的好处是可以卸载加载到新创建的AppDomain中的程序集。如果您在主AppDomain上一遍又一遍地加载更多程序集,那么AppDomain将会异常增长。创建一个单独的AppDomain允许您在每次检查后卸载,然后卸载加载到该域的所有程序集,因此主AppDomain保持清洁。
答案 2 :(得分:1)
我研究了一种(大部分)C ++软件,它允许用户编写脚本以使用C#或VB.NET自动化应用程序。该应用程序还有一些用C#编写的组件。它为程序组件使用了一个AppDomain,另一个用于沙箱脚本。
脚本的原始实现为每个脚本创建了一个AppDomain,但事实证明它太慢并且它阻止了一些有用的脚本行为,所以我们为脚本引擎找到了一个永久的AppDomain。
答案 3 :(得分:1)
您可能希望使用一个来模拟IIS的处理。您需要一个长时间运行的进程来泄漏内存。您可以跟踪AD处理的请求数量以及达到阈值的请求数量,然后启动新的请求。当旧的完成所有处理卸载它并让CLR清理一些app垃圾。
不要问我怎么知道这个。 :)
如果要在不同的安全上下文中运行代码,也可以执行此操作。
答案 4 :(得分:1)
.NET 应用程序在其(单个)进程中创建多个 AppDomain
实例的一个非常有用的场景是管理静态变量的范围一些概念上相关的对象实例的大集合。
例如,考虑一个数据库应用程序,其中 90% 的代码管理一组相互关联的 .NET 对象,这些对象包括所有属于到同一个顶级数据库。在为数据库本身编写代码时,最好让这个对象图中的每个子实例都是自给自足的,这意味着每个对象都携带(通过包含)足够的信息来确定它需要关联的任何/所有上下文到数据库的其余部分,无需任何外部参考。这使您可以传递任何类型的次要实体,而无需担心它内部可能需要什么额外的上下文。
这种便利的代价是整个应用程序中的每个次要子对象都携带它所需的上下文作为内部字段。如果应用程序还需要支持多个数据库,例如允许在数据库之间进行比较、导入或导出操作(比如代码的其他 10%),那么每个对象的上下文必须包含直接或间接区分它最终属于哪个数据库的信息。
这些额外的信息会导致内存膨胀,尤其是在更多的低级实例中,并且对于单个给定的“流行”数据库,根据定义,这种携带的大部分上下文将是重复的。
AppDomain
来拯救... 相反,您的代码的数据库部分可以与每个数据库的不同 AppDomain
相关联。由于静态变量的范围是它们的 AppDomain
,您可以将有关数据库的顶级信息与 AppDomain
相关联,并且每个次要实例都将固有地知道它属于哪个数据库,或者相对于 {{1 }} 静态属性,或者简单地引用您定义的静态字段、属性和方法,所有这些都没有任何额外的每个实例字段。
请注意,数据库间(即 10% 部分)代码以这种方式一次只能引用一个数据库。在此类操作期间,必须(以传统方式)显式引用任何其他数据库。然而,对于大部分代码,这种技术可能会消除部署在所有这些上下文字段中的数百万个对象引用。如果您拒绝全局单例的想法,请注意 AppDomain.CurrentDomain
已经存在于您的 .NET 代码中——所以为什么不好好利用它!