我不了解应用程序域


80

.NET具有“应用程序域”的概念,据我了解,该域可用于将程序集加载到内存中。我已经对“应用程序域”进行了一些研究,还去了我的本地书店以获取有关此主题的更多知识,但这似乎很匮乏。

我所知道的我对应用程序域所能做的就是将程序集加载到内存中,并且可以在需要时卸载它们。

我提到的应用程序域的其他功能是什么?线程是否遵守应用程序域的边界?在通信性能之外,将程序集加载到除主要应用程序域以外的其他应用程序域中是否有任何缺点?

链接到讨论应用程序域的资源也将很好。我已经签出了MSDN,它没有太多关于它们的信息。

Answers:


100

AppDomains的可视化过程非常轻巧。

每个.Net进程可以有N个AppDomain,但通常只有一个。AppDomains的真正优势在于它们在您的过程中提供了隔离边界。对象只能通过远程处理或序列化跨越AppDomain边界彼此通信。

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

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

AppDomains的缺点主要是复杂性。远程处理可能需要一些时间才能使您的头脑动起来,正确设置AppDomain可能是不容易的过程。

您可能需要浏览一下AppDomains上的MSDN文档。很难找到描述它们的简洁教程,因为它们具有多种复杂功能。这提供了一个很好的概述,如果它不能直接回答您的问题,至少可以将您指向正确的位置。

http://msdn.microsoft.com/zh-CN/library/cxk374d9.aspx

不再维护此文档,请参考此以获取更新的版本:https : //msdn.microsoft.com/zh-cn/library/2bh4z9hs(v=vs.110).aspx


4
主要问题是我不了解使用这些功能所获得的功能。我读到它们是一个轻量级的过程,但是它们似乎携带的不仅仅只是那一点,我可能会丢失一些可能在以后咬住我的东西。IE浏览器,我拿出比我需要的更多。
杰里米·爱德华兹

92

JaredPar的回答很好,只是他没有注意到AppDomains的存在理由-也就是说,您只能通过卸载其AppDomain来卸载程序集。如果您是长时间运行的OS进程,并且希望由于某种原因而必须先加载然后再卸载程序集,则需要一个AppDomain。此处的典型示例是ASP.NET,它可以按需加载应用程序代码程序集,然后可以在不再活跃使用应用程序时稍后将其卸载。

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

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

有异常情况。像,假设您要同时加载两个不同版本的程序集。如果不与AppDomains隔离陷阱,则会遇到陷阱。但这将非常罕见。

证明存在AppDomains的核心场景是必须能够卸载程序集的长时间运行的过程。

当然,当您要卸载程序集时,应用程序可能依赖于OS进程。换句话说,您可以运行3个或4个协作进程,每个进程都有其自己的程序集,而当您要卸载程序集时,只需关闭承载该程序集的进程即可。但是AppDomain提供了一种更高性能的机制来执行此操作,而不需要进程停止/启动或跨进程通信,这比前面介绍的跨AppDomain通信还要重。我的意思是它仍在远程处理,但速度较慢,上下文切换更多。


17
如果您觉得必须定义一个单词,为什么要使用它呢?
BlueRaja-Danny Pflughoeft 2010年

44
因为在法语中回答计算机科学问题很有趣。
Cheeso 2010年

13
@ BlueRaja-DannyPflughoeft,它可以帮助教育那些可能不熟悉什么是常用外来术语的人,该术语完美地封装了一个用英语更加笨拙定义的想法。
山姆·霍尔德

6
@SamHolder链接的维基百科文章说,英语翻译是“存在的理由”。在我看来,这似乎不太笨拙。
博格纳尔

5
用我的钱,这是最好的答案,因为据我所知,在MSDN上的任何地方都没有明确说明“理由”。
Dan Ling

27

您可以使用AppDomains进行以下操作:

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

简而言之,它是安全边界,而几乎是过程边界。就性能而言,一个进程中的多个AppDomain并不代表大量开销。启动一个单独的过程而不是一个AppDomain会花费更多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.