我不懂Application Domain

时间:2009-03-07 21:11:37

标签: .net appdomain

.NET有应用域的这个概念,据我所知,可以用来将程序集加载到内存中。我已经对应用程序域做了一些研究,并且去了我当地的书店,了解了这个主题的一些额外知识,但它似乎非常缺乏。

我所知道的我可以使用Application Domains来加载内存中的程序集,我可以在需要时卸载它们。

我提到的应用程序域的其他功能有哪些?线程是否尊重应用程序域边界?除了主要的应用程序域之外,在除了通信性能之外的不同应用程序域中加载程序集是否有任何缺点?

讨论应用程序域的资源链接也很不错。我已经检查过MSDN,它没有那么多关于它们的信息。

3 个答案:

答案 0 :(得分:99)

AppDomains最佳可视化为一个非常轻量级的过程。

每个.Net流程可以有N个AppDomains,但一般来说只有一个。 AppDomains的真正优势在于它们在您的流程中提供了隔离边界。对象只能通过远程处理或序列化在AppDomain边界上相互通信。

还可以在一个进程中以完全不同的安全级别运行2个AppDomain。这可以让您在完全信任的情况下运行主应用程序,同时以低得多的信任级别运行不受信任的插件。

很难对线程是否尊重AppDomain说“是”或“否”。单个线程可能位于N个不同的AppDomain中。如果一个AppDomain中的对象对另一个AppDomain中的对象进行远程调用,则可能出现这种情况。该线程必须在AppDomains之间进行转换才能完成。

AppDomains的缺点主要是复杂性。远程处理可能需要一点时间来解决问题,正确设置AppDomain可能是一个非常重要的过程。

您可能希望了解AppDomains上的MSDN文档。很难找到描述它们的succint教程,因为它们具有各种复杂的功能。这提供了一个很好的概述,如果它没有直接回答你的问题,至少会指出你在正确的位置。

http://msdn.microsoft.com/en-us/library/cxk374d9.aspx

此文档已不再维护,请参阅此更新版本: https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx

答案 1 :(得分:91)

JaredPar的回答很好,除了他没有注意到AppDomains的raison d'etre - 这是你只能通过卸载它的AppDomain来卸载程序集。如果您是一个长期运行的操作系统进程,并且您希望必须加载然后再卸载程序集,那么您需要一个AppDomain。这里的典型示例是ASP.NET,它根据需要加载应用程序代码程序集,然后在应用程序不再被主动使用时可以在以后卸载它们。

您为卸载能力支付的成本是独立性 - 您需要跨AppDomain边界进行通信,无法进行简单的方法调用。您需要管理AppDomain生命周期。等等。

如果你只是需要动态加载程序集而不认为你需要在单个进程的生命周期中卸载它们那么你可能需要运行多个AppDomain。这里的一个很好的例子可能是一个支持插件模型的丰富应用程序,它可以在“etc”目录中嗅出插件程序集并加载它们。但是,如果插件模型要求卸载插件......那么。

有一些特殊情况。比如,假设您想要同时加载2个不同版本的程序集。如果不将它们与AppDomains隔离,则可能会遇到陷阱。但那将是相当罕见的。

证明AppDomains存在的核心方案是长时间运行的进程,必须能够卸载程序集。

当然,当您要卸载程序集时,应用程序可能依赖于OS进程。换句话说,您可以运行3个或4个协作进程,每个进程都有自己的程序集,当您要卸载程序集时,只需关闭承载该程序集的进程即可。但AppDomain提供了更高性能的机制来实现这一点,而不需要进程停止/启动或跨进程通信,这比前面描述的跨AppDomain通信更重。我的意思是它仍然是遥控器,但它更慢,更多的上下文切换。

答案 2 :(得分:27)

您可以使用AppDomains执行的一些操作:

  • 您可以关闭它而不会危及程序的稳定性。
  • 您可以加载代码,并为您提供比自己的流程更少的权限(例如,您的流程完全受信任,但您在单独的AppDomain中加载代码,甚至无法在磁盘上创建文件。)
  • 您可以处理AppDomain的未处理异常,而不必崩溃您的进程。

简单地说,它是一个安全边界,而且只是一个过程边界。就性能而言,进程中的多个AppDomain并不代表显着的开销。启动单独的进程而不是AppDomain的成本要高得多。