C# AppDomain使用方法 C# AppDomain是什么以及如何使用

来源:这里教程网 时间:2026-02-21 17:41:36 作者:

AppDomain 在现代 C# 中基本已弃用

从 .NET Core 1.0 开始,

AppDomain
类型就不再被支持;.NET 5+ 完全移除了它。如果你正在写新项目(尤其是面向 .NET 5/6/7/8),
AppDomain
不是可用选项——不是“怎么用”的问题,而是“不能用”。仅在维护遗留的 .NET Framework(4.x)桌面应用时才可能遇到它。

为什么 AppDomain 曾被用于隔离程序集

在 .NET Framework 时代,

AppDomain
是进程内的逻辑隔离边界,主要用来:

动态加载/卸载程序集(
Assembly.LoadFrom
加载后无法卸载,但放在独立
AppDomain
中可整体卸载)
限制权限(配合
AppDomain.CreateDomain
PermissionSet
参数)
捕获未处理异常(
AppDomain.CurrentDomain.UnhandledException

但它的隔离性并不彻底(共享类型对象、静态字段仍可能跨域泄漏),且性能开销大、调试困难,早已被更轻量的方案替代。

替代 AppDomain 的现代做法

对应旧有需求,现在应转向:

动态加载与卸载程序集:使用
AssemblyLoadContext
(.NET Core+),支持
Unload()
;需手动管理上下文生命周期,避免内存泄漏
沙箱/权限控制:改用操作系统级隔离(容器、进程)、代码签名 + 运行时策略,或最小权限原则设计 API 边界 全局异常捕获:仍可用
AppDomain.CurrentDomain.UnhandledException
—— 但注意:该事件在 .NET Core+ 中只是兼容保留,仅对主线程同步异常有效;推荐统一用
try/catch
+
TaskScheduler.UnobservedTaskException
+
Application.ThreadException
(Windows Forms)组合覆盖

如果必须在 .NET Framework 中操作 AppDomain

仅限维护老项目,且明确运行于 full framework(如 Windows Server 2012 + .NET 4.8)。关键点:

不要直接 new
AppDomain
,用
AppDomain.CreateDomain("name")
跨域调用必须继承
MarshalByRefObject
,否则会被序列化传值(导致类型加载失败或状态丢失)
卸载前确保无引用残留(尤其事件订阅、线程、Timer),否则
AppDomain.Unload()
会阻塞甚至超时抛
CannotUnloadAppDomainException
AppDomainSetup.ApplicationBase
必须设为绝对路径,否则加载程序集易失败

示例片段(仅作对照,勿复制到新项目):

var setup = new AppDomainSetup { ApplicationBase = @"C:\MyPlugins" };
var domain = AppDomain.CreateDomain("PluginDomain", null, setup);
domain.DoCallBack(() => Console.WriteLine("Running in isolated domain"));
AppDomain.Unload(domain); // 可能卡住,务必检查引用

真正棘手的是卸载失败的排查——没有工具能自动追踪所有跨域引用,只能靠日志、弱引用检测和反复重启测试。

相关推荐