使用AppDomain的很好的例子
在面试中我一直被问及AppDomain, 我知道基本知识 :
- 它们是应用程序内的隔离级别(使它们与应用程序不同)
- 他们可以有线程(使他们不同于线程)
- 一个appdomain中的exception不会影响另一个
- AppDomain无法访问彼此的内存
- 每个appdomain可以有不同的安全性
我仍然没有得到什么使他们的必要。 我正在寻找一个合理的具体情况,当你使用一个。
回答:
- 不可信的代码
- 核心应用受保护
不受信任/第三方插件被禁止破坏共享内存和未经授权的访问registry或硬盘驱动器隔离在单独的具有安全限制的appdomain,保护应用程序或服务器。 例如ASP.NET和SQL Server托pipe组件代码 - 可信的代码
- 稳定性
应用程序分为安全,独立的function/function - build筑灵活性
自由地在单个CLR实例或每个程序中运行多个应用程序。
还要别的吗?
最常见的可能是加载包含来自不受信任方的插件代码的程序集。 代码在自己的AppDomain中运行,隔离应用程序。
此外,不能卸载特定的程序集,但可以卸载AppDomain。
Chris Brumme对此有详尽的博客介绍:
AppDomain的另一个好处(就像你在你的问题中提到的那样)是你加载到它的代码可以运行不同的安全权限。 例如,我写了一个dynamic加载DLL的应用程序。 我是一名教练,这些是我加载的学生DLL。 我不想让一些心怀不满的学生消灭我的硬盘驱动器或损坏我的registry,所以我将代码从他们的DLL加载到一个单独的AppDomain,没有文件IO权限或registry编辑权限,甚至没有显示新窗口的权限(它实际上只有执行权限)。
我认为拥有AppDomain的主要动机是CLRdevise者想要一种隔离托pipe代码的方式,而不会导致多个Windows进程的性能开销。 如果CLR最初是在UNIX之上实现的(创build多个进程的成本显着降低),AppDomains可能永远不会被发明出来。
另外,虽然第三方应用程序中的托pipe插件架构无疑是AppDomain的一个很好的使用方式,但是它们存在的更大的原因是SQL Server 2005和ASP.NET等知名主机。 例如,ASP.NET托pipe提供商可以提供一个共享托pipe解决scheme,该解决scheme支持多个客户的多个站点,这些站点都在同一个Windows操作系统下运行。
应用程序域对于应用程序稳定性非常好。
通过让应用程序由一个中央进程组成,然后在单独的应用程序域中产生“function”,如果其中一个失败,则可以防止全局崩溃。
如果您创build的应用程序允许使用第三方插件,则可以将这些插件加载到单独的AppDomain中,以便您的主应用程序可以安全使用未知代码。
对于单个工作进程中的每个Web应用程序,ASP.NET也使用单独的AppDomain。
据我了解,AppDomain的devise允许托pipe实体(操作系统,数据库,服务器等)自由地在单个CLR实例或每个程序中运行多个应用程序。 所以它是主机而不是应用程序开发人员的问题。
与那些每个应用程序总是有1个JVM的Java相比,这种情况比较好,通常会导致JVM的许多实例并行运行,并且具有重复的资源。
我看到2个或3个主要用例来创build单独的应用程序域:
1)过程般的隔离,资源使用和开销较低。 例如,这就是ASP.NET所做的 – 它将每个网站托pipe在一个单独的应用程序域中。 如果在单个应用程序域中使用不同的线程,则不同网站的代码可能会相互干扰。 如果在不同的进程中托pipe不同的网站,那么与进程间通信相比,它将占用大量资源,并且进程间通信也相对困难。
2)在具有特定安全权限的独立应用程序域中执行不可信代码(这实际上与第一个原因有关)。 正如人们已经说过的,您可以将第三方插件或不受信任的dll加载到单独的应用程序域中。
3)能够卸载程序集以减less不必要的内存使用。 不幸的是,没有办法从应用程序域卸载程序集。 所以,如果你加载一些大的程序集到你的主应用程序域,在程序集之后释放相应内存的唯一方法就是不再需要closures你的应用程序。 将程序集加载到单独的应用程序域中,并在不再需要这些程序集时卸载该应用程序域是解决此问题的方法。
- 如何使用entity framework中的DataBase中的默认列值?
- ClickOnce错误:值不在预期范围内
- 用更好的浏览器代替.NET WebBrowser控件,比如Chrome?
- 在Visual Studio 2012中的纯C#编辑器(没有智能感知,没有缩进,没有代码高亮)
- 将parameter passing给模板types的C#genericsnew()
- Stream.Seek(0,SeekOrigin.Begin)或者Position = 0
- 仅从DateTime对象获取date或时间
- .NET中的IEqualityComparer <T>中GetHashCode的作用是什么?
- 为什么没有setter的属性没有被序列化