使用AppDomain的很好的例子

在面试中我一直被问及AppDomain, 我知道基本知识 :

  • 它们是应用程序内的隔离级别(使它们与应用程序不同)
  • 他们可以有线程(使他们不同于线程)
  • 一个appdomain中的exception不会影响另一个
  • AppDomain无法访问彼此的内存
  • 每个appdomain可以有不同的安全性

我仍然没有得到什么使他们的必要。 我正在寻找一个合理的具体情况,当你使用一个。

回答:

  • 不可信的代码
    • 核心应用受保护
      不受信任/第三方插件被禁止破坏共享内存和未经授权的访问registry或硬盘驱动器隔离在单独的具有安全限制的appdomain,保护应用程序或服务器。 例如ASP.NET和SQL Server托pipe组件代码
  • 可信的代码
    • 稳定性
      应用程序分为安全,独立的function/function
    • build筑灵活性
      自由地在单个CLR实例或每个程序中运行多个应用程序。

还要别的吗?

最常见的可能是加载包含来自不受信任方的插件代码的程序集。 代码在自己的AppDomain中运行,隔离应用程序。

此外,不能卸载特定的程序集,但可以卸载AppDomain。

Chris Brumme对此有详尽的博客介绍:

http://blogs.msdn.com/cbrumme/archive/2003/06/01/51466.aspx

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你的应用程序。 将程序集加载到单独的应用程序域中,并在不再需要这些程序集时卸载该应用程序域是解决此问题的方法。