应用程序域用于什么?

我大致了解AppDomain是什么,但是我并不完全理解AppDomain的用途。

我参与了一个基于服务器的大型C#/ C ++应用程序,我想知道如何使用AppDomains来提高稳定性/安全性/性能。

特别是:

  • 我理解一个域中的错误或致命exception不会影响在同一进程中运行的其他应用程序域 – 这是否也适用于非托管/ C ++exception,甚至可能是堆损坏或其他内存问题。
  • AppDomain间通信如何工作?
  • 如何使用AppDomains与简单地生成许多进程有什么不同?

AppDomain的基本用例是在托管第三方代码的环境中,因此不仅需要动态加载程序集,还需要卸载它们

没有办法单独卸载组件。 因此,您必须创建一个单独的AppDomain来容纳可能需要卸载的任何内容。 然后,您可以在必要时删除并重建整个AppDomain。

顺便说一句,破坏堆的本机代码无法受到CLR的任何function的保护。 最终,CLR本地实现并共享相同的地址空间。 因此,流程中的本机代码可以遍布CLR的内部! 隔离行为不当(即大多数)本机代码的唯一方法是在操作系统级别进行实际进程隔离。 启动多个.exe进程并让它们通过某种IPC机制进行通信。

我强烈推荐Jeffrey Richter的CLR Via C# 。 特别是第21章详细介绍了AppDomains的用途和用途。

回答你的观点/问题:

  • AppDomains不会保护您的应用程序免受恶意非托管代码的侵害。 如果这是一个问题,您很可能需要使用操作系统提供的完全进程隔离。

  • AppDomains之间的通信使用.NET远程执行来强制隔离。 这可以通过引用编组或按值语义编组,在性能和灵活性之间进行权衡。

  • AppDomains是一种在托管代码中实现隔离等过程的轻量级方法。 AppDomains被认为是轻量级的,因为您可以在单个进程中创建多个AppDomain,因此它们可以避免多个OS进程的资源和性能开销。 此外,单个线程可以在一个AppDomain中执行代码,然后在另一个AppDomain中执行代码,因为Windows对AppDomains一无所知(请参阅使用System.AppDomain.CurrentDomain)

实际上,一个AppDomain中的严重故障不会影响其他AppDomain 。 在坏事的情况下,最好还是打破这个过程。 有几个例子,但老实说我没有记住它们 – 我只是记下了一个“坏事”=“拆除过程(检查)”

AppDomain好处:

  • 你可以卸载一个AppDomain ; 我将它用于一个基于来自数据库的数据编译自身(元编程)的系统 – 它可以启动一个appdomain来托管新的dll一段时间,然后在新数据可用(并构建)时安全地交换它
  • AppDomain之间的通信相对便宜。 IMO这是唯一一次我很乐意使用远程处理(尽管你仍然需要非常小心边界上的对象以避免它们之间出现引用,导致“融合”将额外的dll加载到主AppDomain ,导致泄漏) – 它也很容易 – 只是CreateInstanceAndUnwrap (或者它是CreateInstanceFromAndUnwrap ?)。
  • vs一个额外的过程 – 你可以去任何一个方向; 但是你不需要另一个用于AppDomain工作的exe,并且设置你需要的任何通信要容易得多

我并不是自称是AppDomains的专家,所以我的回答并不是无所不包。 也许我应该首先链接到一个有点专家的人的精彩介绍,以及看起来覆盖AppDomain使用的所有方面的内容 。

我自己与AppDomains的主要遭遇是在安全领域。 在那里,我发现的最大优势是能够以高信任度运行主域,从而产生具有受限权限的多个子域。 通过限制高信任度的权限,而不使用应用程序域,受限制的进程仍然可以提升自己的权限。

用于运行完全独立的代码模块的App Domain隔离策略,以解决内存共享和稳定性问题,更多的是一种错觉而非现实。