使用AppDomain的好例子

时间:2008-09-18 21:59:42

标签: .net appdomain

我在面试时不断被问及AppDomains,I know the basics

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

我仍然没有得到必要的东西。当你使用它时,我正在寻找一个合理的具体情况。

数目:

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

还有别的吗?

7 个答案:

答案 0 :(得分:49)

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

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

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

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

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

答案 1 :(得分:14)

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

答案 2 :(得分:8)

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

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

答案 3 :(得分:4)

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

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

答案 4 :(得分:4)

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

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

答案 5 :(得分:4)

据我所知,AppDomain旨在允许托管实体(操作系统,数据库,服务器等)在单个CLR实例或每个程序中运行多个应用程序。因此它对于主机而不是应用程序开发人员来说是一个问题。

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

答案 6 :(得分:3)

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

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

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

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