AppDomain 是不是等同于 .NET 代码的进程?

Posted

技术标签:

【中文标题】AppDomain 是不是等同于 .NET 代码的进程?【英文标题】:Is AppDomain equivalent to a Process for .NET code?AppDomain 是否等同于 .NET 代码的进程? 【发布时间】:2009-08-10 05:27:36 【问题描述】:

我不得不调用一些写得很糟糕的第 3 方 COM 组件,它们存在内存泄漏并在长时间运行的进程中使用单线程单元 [STA]。

我知道单独的进程将是实现它的好方法,我可以偶尔从长时间运行的进程中重新启动它。

可以使用 AppDomain 代替吗?如果标记得当,AppDomain 线程是 STA 线程吗?它是否有自己的 COM 对象内存?卸载AppDomain是否相当于杀死进程?

【问题讨论】:

【参考方案1】:

AppDomain 不能提供与进程相同程度的隔离。事实上,如果您担心第 3 方组件状态不佳,则存在风险,即它会关闭您的 .NET 应用程序。

如果卸载时正在执行非托管代码,则无法卸载 AppDomain,因此您可能很难控制 AppDomain 中的第 3 方代码。见http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx

即使仅适用于托管代码,AppDomain 也不提供强大的沙盒解决方案。例如。如果加载的代码产生任何线程,这些线程将在出现未处理的异常时关闭整个进程。这个问题有更多信息:.NET - What's the best way to implement a "catch all exceptions handler"。

据我所知,在 .NET 应用程序中托管此类代码的最佳选择是实现您自己的 CLR 托管进程,例如 IIS 和 SQL Server。

【讨论】:

【参考方案2】:

AppDomain(应用程序域)是应用程序执行的隔离环境。

它们有助于提供隔离, 卸载和安全边界 执行托管代码。

使用应用程序域来隔离可能导致进程中断的任务。 如果 AppDomain 的状态是 执行任务变得不稳定, AppDomain 可以不卸载 影响进程。这是 当一个进程必须运行时很重要 长时间不重启。你 也可以使用应用程序域 隔离不应该共享的任务 数据。

如果程序集被加载到默认应用程序域,它不能 被从内存中卸载,而 进程正在运行。但是,如果你 打开第二个应用程序域 加载并执行程序集, 程序集被卸载时 应用程序域已卸载。采用 这种技术,以尽量减少工作 一组长时间运行的进程 偶尔使用大型 DLL。

可以运行多个应用程序域 在一个过程中;然而,有 之间不是一一对应的 应用程序域和线程。 多个线程可以属于一个 应用程序域,而给定的 线程不限于单个 应用程序域,在任何给定时间, 一个线程在单个中执行 应用领域。

可能感兴趣的问题:

What is a .Net app domain?

I don’t understand AppDomains

我不会自称是 AppDomain 领域的专家,但我相当肯定 COM 对象泄漏内存(即非托管内存)不会通过卸载 AppDomain 来释放。也许对此更熟悉的人可以发表评论。

正如 Brian 指出的那样,“......在 .NET Framework 2.0 版域中不能保证卸载,因为它可能无法终止正在执行的线程。”

【讨论】:

我也很想知道答案是什么。我现在没有可以提供的。

以上是关于AppDomain 是不是等同于 .NET 代码的进程?的主要内容,如果未能解决你的问题,请参考以下文章

Java 包是不是等同于 .Net 程序集?

替换 Net Core 中的 AppDomain

在 .NET 中,创建新的 AppDomain 时是不是调用静态构造函数?

ASP.Net 是不是曾经在默认的 AppDomain 中运行?

.Net 同一个程序集的两个版本在一个 AppDomain 中加载时是不是存在潜在问题?

.Net AppDomain详解