50

我在面试中不断被问到关于 AppDomains 的问题,我知道基础知识

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

我仍然不明白是什么让它们变得必要。我正在寻找一个合理的具体情况,当你会使用一个。

答案:

  • 不受信任的代码
    • 受核心应用程序保护
      的不受信任/第 3 方插件通过隔离在具有安全限制的单独应用程序域中来防止损坏共享内存和对注册表或硬盘驱动器的非授权访问,从而保护应用程序或服务器。例如 ASP.NET 和 SQL Server 托管组件代码
  • 可信代码
    • 稳定性
      应用程序细分为安全、独立的特性/功能
    • 架构灵活性
      在单个 CLR 实例或每个程序中运行多个应用程序的自由。

还要别的吗?

4

7 回答 7

50

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

此外,无法卸载特定程序集,但您可以卸载 AppDomain。

对于完整的纲要,Chris Brumme 有一篇关于此的大量博客文章:

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

https://devblogs.microsoft.com/cbrumme/appdomains-application-domains/

于 2008-09-18T22:01:20.687 回答
16

AppDomains 的另一个好处(正如您在问题中提到的)是您加载到其中的代码可以使用不同的安全权限运行。例如,我编写了一个动态加载 DLL 的应用程序。我是一名讲师,这些是我正在加载的学生 DLL。我不想让一些心怀不满的学生清除我的硬盘或损坏我的注册表,所以我将代码从他们的 DLL 加载到一个单独的 AppDomain 中,该 AppDomain 没有文件 IO 权限或注册表编辑权限,甚至没有显示新窗口的权限(它实际上只有执行权限)。

于 2008-09-18T23:13:26.987 回答
8

我认为拥有 AppDomains 的主要动机是 CLR 设计人员想要一种隔离托管代码的方法,而不会导致多个 Windows 进程的性能开销。如果 CLR 最初是在 UNIX 之上实现的(在 UNIX 上创建多个进程的成本要低得多),那么 AppDomains 可能永远不会被发明出来。

此外,虽然 3rd 方应用程序中的托管插件体系结构绝对是 AppDomains 的一个很好的用途,但它们存在的更大原因是用于 SQL Server 2005 和 ASP.NET 等知名主机。例如,ASP.NET 托管服务提供商可以提供一个共享托管解决方案,该解决方案支持来自多个客户的多个站点,所有这些站点都位于在单个 Windows 进程下运行的同一机器上。

于 2008-09-18T22:50:35.420 回答
4

如果您创建允许第三方插件的应用程序,您可以将这些插件加载到单独的 AppDomain 中,以便您的主应用程序不受未知代码的影响。

ASP.NET 还为单个工作进程中的每个 Web 应用程序使用单独的 AppDomain。

于 2008-09-18T22:02:13.210 回答
4

应用程序域非常适合应用程序稳定性。

通过让您的应用程序包含一个中央进程,然后在单独的应用程序域中产生“功能”,您可以防止其中一个行为不端时发生全局崩溃。

于 2008-09-18T22:08:46.550 回答
4

据我了解,AppDomain 旨在允许托管实体(操作系统、数据库、服务器等)自由地在单个 CLR 实例或每个程序中运行多个应用程序。所以这是主机而不是应用程序开发人员的问题。

这与 Java 相比是有利的,在 Java 中每个应用程序总是有 1 个 JVM,这通常会导致许多 JVM 实例与重复资源并行运行。

于 2008-09-18T22:12:43.983 回答
3

我看到 2 或 3 个用于创建单独应用程序域的主要用例:

1)具有低资源使用和开销的类似进程的隔离。例如,这就是 ASP.NET 所做的——它将每个网站托管在一个单独的应用程序域中。如果它在单个应用程序域中使用不同的线程,那么不同网站的代码可能会相互干扰。如果它在不同的进程中托管不同的网站 - 它将使用大量资源,并且与进程内通信相比,进程间通信相对困难。

2)在具有特定安全权限的单独应用程序域中执行不受信任的代码(这实际上与第一个原因有关)。正如人们已经说过的,您可以将 3rd 方插件或不受信任的 dll 加载到单独的应用程序域中。

3)能够卸载程序集以减少不必要的内存使用。不幸的是,没有办法从应用程序域中卸载程序集。因此,如果您将一些大型程序集加载到您的主应用程序域,那么在不再需要该程序集之后释放相应内存的唯一方法是关闭您的应用程序。在单独的应用程序域中加载程序集并在不再需要这些程序集时卸载该应用程序域是解决此问题的方法。

于 2011-02-19T02:35:23.570 回答