C#中AppDomain的使用
Posted
技术标签:
【中文标题】C#中AppDomain的使用【英文标题】:Usage of AppDomain in C# 【发布时间】:2009-03-20 10:52:40 【问题描述】:AppDomain 在 C# 中最重要的用途是什么?
【问题讨论】:
请阅读我的博客,了解运行时加载 DLL 和使用 AppDomain 进行交叉通信的标准应用程序。 blog.vcillusion.co.in/… 【参考方案1】:最重要的一个用途是您的代码必须有一个 - 即您用 C# 编写的所有内容都在 AppDomain
中执行。这很重要;-p
如果您的意思是附加应用程序域:
当使用插件和其他不受信任的代码时,它允许您进行隔离和卸载它们的能力(您不能卸载程序集 - 只能卸载整个应用程序域)。
我目前正在使用它来加载动态生成的 dll,以便我可以卸载它们。
它们还允许您设置不同的配置文件、信任级别等 - 但具有相关的复杂性和远程处理成本。
MSDN 有一个关于应用程序域的部分,here。
【讨论】:
【参考方案2】:我不能告诉你最重要的用途是什么,因为这取决于具体情况。
AppDomain 对于应用程序的沙盒化部分很有用。您可以在 AppDomain 中加载扩展并再次卸载它们 - 这是您无法做到的。您可以将特定权限分配给 AppDomain。默认情况下,不同 AppDomain 中的对象不能相互访问。
AppDomain 可以被视为轻量级进程,因为它们为您提供了许多相同的功能。但是,与 Process 不同,新的 AppDomain 默认没有自己的线程。您必须自己管理 AppDomain 和线程。
此外,AppDomain 都共享同一个托管堆。这通常不是问题,但它可能会产生令人惊讶的效果,因为某些实例(如字符串)在 AppDomain 之间共享。对于常规使用,这不是问题,但如果您使用字符串进行锁定,不同 AppDomain 中的线程可能会相互影响。
【讨论】:
关于字符串的注意事项。 "AppDomains 都共享同一个托管堆。"这是否意味着它们也共享静态类或静态方法? @Mathematics 这只是意味着它们的堆都在 CLR 创建的同一个托管堆中。每个 AppDomain 不与任何其他共享其托管堆,否则它们将交叉引用实例,这是不允许的,并且 2 个 AppDomain 之间的数据交换只是按值复制【参考方案3】:一般来说,使用 AppDomains 并不是日常的编码实践,这可以被认为是一个高级概念。但是,从这个简单的事情开始,更好地理解“AppDomain”这个词背后的概念很重要。
就架构而言,尽可能简单,即使在内存寻址方面,AppDomain 也是一个隔离容器,在其中加载和执行应用程序所需的所有程序集,即使这个概念更复杂详细解释(我希望这不是你的问题要深入)。
从那里开始,AppDomain 类首先用于获取对应用程序相关执行应用程序域的访问,这可以通过 Singleton 属性实现AppDomain.CurrentDomain
来完成。这样可以:
-
获取已加载程序集的访问权限;
获得对 appdomain 共享数据槽的访问权限;
intems marshalling,即从已创建域中加载的程序集中解开已创建实例。
那么,AppDomain 类用于:
-
在同一进程中创建更多“域”;
在进程中执行程序集;
管理 appdomain 的加载/卸载过程。
查看新的 Microsoft 框架(尚未发布)MEF (Managed Extesibility Framework) 的代码可能会很有用,它真正基于 AppDomains 创建和卸载、动态加载的程序集等概念。
作为一个简单的例子和你可以用 AppDomains 做什么的例子,我可以分享这个link。
希望我回答了你的问题。
【讨论】:
【参考方案4】:C# AppDomain 是一个逻辑隔离的容器,.NET 代码在其中运行。当您运行任何 .NET 代码时,它总是在默认的应用程序域中运行。
请观看这个 30 分钟的 youtube 视频 What is C# AppDomain ?,它更详细地解释了 AppDomain。
但还是让我试着更详细地解释一下。假设您获得了第三方 DLL,并且您想在您的应用程序中使用它。但是您也怀疑第三方可能有一些恶意代码,因此您希望在受限环境中运行第三方 DLL。比如你不想让第三方访问你的c:盘或者删除文件等等。
因此您可以创建两个 AppDomain,一个用于第三方,一个用于您自己的 C# 类。对于第三方应用程序域,您将应用它无法访问 c: 驱动器的安全约束,而对于您的 C# DLL,您将拥有一个不受限制的应用程序域。
【讨论】:
【参考方案5】:请阅读我的博客,了解运行时加载 DLL 和使用 AppDomain 进行交叉通信的标准应用程序。 https://blog.vcillusion.co.in/sending-events-through-application-domain-boundary/
-
DLL 的运行时加载和卸载:我在一个项目中工作,其中 DLL 由用户在运行时加载,在程序执行期间,使用反射执行方法并在程序运行期间卸载。
保护我的主执行程序:我们正在动态加载 DLL,因此动态加载的 DLL 中发生的任何异常都不会影响我的主 AppDomain。如果出现损坏情况,我们可以选择高效地再次卸载和加载 DLL。
跨AppDomain通信:我们可以在运行时在不同的AppDomain中动态加载任意两个DLL,使它们相互通信。
【讨论】:
以上是关于C#中AppDomain的使用的主要内容,如果未能解决你的问题,请参考以下文章