使用AppDomain的好例子
在采访中,我不断被问到有关AppDomain的问题,我知道一些基本知识:
- 它们是应用程序中的隔离级别(使它们与应用程序不同)
- 他们可以有线程(使它们不同于线程)
- 一个应用程序域中的异常不会影响另一应用程序域
- 应用程序域无法访问彼此的内存
- 每个应用程序域可以具有不同的安全性
我仍然不明白什么使他们必要。我正在寻找一个合理的具体环境,以供我们使用。
答案:
- 不受信任的代码
- 受核心应用程序保护的不受信任/第三方插件被禁止破坏共享内存,并且通过在单独的应用程序域中进行隔离(具有安全性限制)可以防止未经授权访问注册表或者硬盘驱动器,从而保护应用程序或者服务器。例如ASP.NET和SQL Server托管组件代码
- 受信任的代码
- 稳定性应用程序分为安全,独立的特征/功能
- 架构灵活性自由地在单个CLR实例或者每个程序中运行多个应用程序。
还要别的吗?
解决方案
可能最常见的一种方法是加载包含来自不受信任方的插件代码的程序集。该代码在其自己的AppDomain中运行,从而隔离了该应用程序。
另外,不可能卸载特定的程序集,但是我们可以卸载AppDomains。
对于完整的摘要,克里斯·布鲁姆(Chris Brumme)对此有大量博客条目:
http://blogs.msdn.com/cbrumme/archive/2003/06/01/51466.aspx
如果创建允许第三方插件的应用程序,则可以将这些插件加载到单独的AppDomain中,以使主应用程序免受未知代码的侵害。
ASP.NET还在单个工作进程中为每个Web应用程序使用单独的AppDomain。
应用程序域对于提高应用程序的稳定性非常有用。
通过使应用程序包含一个中央进程,然后在单独的应用程序域中生成"功能",可以防止全局崩溃(如果其中一个行为异常)。
据我了解,AppDomain旨在允许托管实体(操作系统,数据库,服务器等)自由地在单个CLR实例或者每个程序中运行多个应用程序。因此,这对于主机而不是应用程序开发人员来说是一个问题。
与Java相比,Java在Java中每个应用程序始终拥有1个JVM,这常常导致JVM的许多实例与重复的资源并排运行。
我认为拥有AppDomains的主要动机是CLR设计人员想要一种隔离托管代码的方法,而不会产生多个Windows进程的性能开销。如果CLR最初是在UNIX之上实现的(创建多个进程的成本要便宜得多),则可能永远不会发明AppDomain。
同样,尽管第三方应用程序中的托管插件体系结构绝对是AppDomain的很好用法,但它们存在的更大原因是使用知名主机,例如SQL Server 2005和ASP.NET。例如,ASP.NET托管提供程序可以提供共享的托管解决方案,该解决方案支持来自多个客户的多个站点,这些站点都在单个Windows进程下运行的同一机器上。
AppDomains的另一个好处(如我们在问题中所提到的)是我们加载到其中的代码可以使用不同的安全权限运行。例如,我编写了一个动态加载DLL的应用程序。我是一名讲师,这些是我正在加载的学生DLL。我不想让一些心怀不满的学生消灭我的硬盘驱动器或者破坏我的注册表,所以我将代码从他们的DLLs加载到了一个单独的AppDomain中,该AppDomain没有文件IO权限,注册表编辑权限甚至不具有显示新窗口的权限(它实际上仅具有执行权限)。