.NET 具有应用程序域的概念,据我了解,它可用于将程序集加载到内存中。我已经对应用程序域进行了一些研究,并去我当地的书店了解了关于这个主题的一些额外知识,但它似乎非常稀缺。
我所知道的我可以对应用程序域做的就是在内存中加载程序集,我可以在需要时卸载它们。
我提到的应用程序域的其他功能是什么?线程是否尊重应用程序域边界?除了通信性能之外,在主要应用程序域之外的不同应用程序域中加载程序集是否有任何缺点?
链接到讨论应用程序域的资源也很好。我已经查看了 MSDN,它没有太多关于它们的信息。
AppDomains 最好被可视化为一个非常轻量级的过程。
每个 .Net 进程可以有 N 个 AppDomain,但一般来说只有一个。AppDomains 的真正优势在于它们在您的流程中提供了隔离边界。对象只能通过远程处理或序列化跨 AppDomain 边界相互通信。
也可以在一个进程中以完全不同的安全级别运行 2 个 AppDomain。这可以让您以完全信任运行您的主应用程序,同时以低得多的信任级别运行不受信任的插件。
很难对线程是否尊重 AppDomain 说“是”或“否”。单个线程可能位于 N 个不同的 AppDomain 中。如果一个 AppDomain 中的对象对另一个 AppDomain 中的对象进行远程调用,则可能会出现这种情况。线程必须在 AppDomain 之间转换才能完成。
AppDomains 的缺点主要是复杂。远程处理可能需要一点时间来了解并正确设置 AppDomain 可能是一个不平凡的过程。
您可能想浏览一下 AppDomains 上的 MSDN 文档。很难找到描述它们的简洁教程,因为它们具有各种复杂的功能。这提供了一个很好的概述,如果它不直接回答您的问题,至少会为您指出正确的位置。
http://msdn.microsoft.com/en-us/library/cxk374d9.aspx
此文档不再维护,请参阅此更新版本: https ://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx
JaredPar 的回答很好,只是他没有指出 AppDomain 存在的理由——即您只能通过卸载 AppDomain 来卸载程序集。如果您是一个长期运行的操作系统进程,并且您希望出于任何原因必须加载然后卸载程序集,那么您需要一个 AppDomain。这里的典型示例是 ASP.NET,它按需加载应用程序代码程序集,然后可以在以后不再使用应用程序时卸载它们。
你为卸载能力付出的代价就是独立性——你需要跨 AppDomain 边界进行通信,不能进行简单的方法调用。您需要管理 AppDomain 生命周期。等等。
如果您只需要动态加载程序集并且认为在单个进程的生命周期内不需要卸载它们,那么您可能不需要运行多个 AppDomain。一个很好的例子可能是一个支持插件模型的富应用程序,它在“etc”目录中嗅出插件程序集并加载它们。但是,如果插件模型要求卸载插件......好吧。
有一些异常情况。就像,假设您想同时加载 2 个不同版本的程序集。如果您不使用 AppDomain 将它们隔离,您可能会遇到陷阱。但这将是相当罕见的。
证明 AppDomains 存在的核心场景是必须能够卸载程序集的长时间运行的进程。
当然,当您要卸载程序集时,应用程序可以依赖操作系统进程。换句话说,您可以运行 3 或 4 个协作进程,每个进程都有自己的程序集集,当您想要卸载程序集时,只需关闭承载该程序集的进程即可。但是 AppDomain 提供了更高性能的机制来做到这一点,不需要进程停止/启动或跨进程通信,这仍然比前面描述的跨 AppDomain 通信更重。我的意思是它仍在远程处理,但速度较慢且上下文切换更多。
您可以使用 AppDomain 执行以下操作:
简单地说,它是一个安全边界,而且几乎是一个进程边界。就性能而言,一个进程中的多个 AppDomain 并不代表显着的开销。启动单独的进程而不是 AppDomain 的成本要高得多。