【笔记】AppDomain.CurrentDomain详细功能介绍
AppDomain.CurrentDomain 的“详解 + 实用指南”,重点覆盖属性、事件、方法、常见用法与注意事项,并结合 WPF 桌面场景。一、定位二、核心事件(最常用)三、常用属性四、常用方法与数据存取五、程序集解析(AssemblyResolve)典型用法六、与 WPF/桌面程序的搭配建议七、限制与陷阱结论。
·
AppDomain.CurrentDomain 的“详解 + 实用指南”,重点覆盖属性、事件、方法、常见用法与注意事项,并结合 WPF 桌面场景。
一、定位
- 类型:System.AppDomain
- CurrentDomain:返回当前线程所在线程的应用程序域(默认域或你创建的自定义域)。
- 作用:管理程序集加载/解析、异常/退出生命周期、域级数据存取与隔离。
二、核心事件(最常用)
- ProcessExit:进程即将退出(调用 Application.Shutdown 或进程终止时)。适合做最终持久化、日志刷写、释放资源。
- DomainUnload:当前 AppDomain 卸载时触发(默认域通常在进程退出时卸载)。
- UnhandledException:当前域中未捕获异常。用于最后兜底日志,但不能保证可恢复。
- FirstChanceException:异常首次被抛出时(即使后续被捕获),用于调试或细粒度日志。
- AssemblyLoad:程序集已加载(通知)。
- AssemblyResolve:解析失败时动态提供程序集(从自定义目录/嵌入资源加载)。
- TypeResolve/ResourceResolve/ReflectionOnlyAssemblyResolve:类型/资源/仅反射加载解析失败时提供回退。
示例(注册/解绑):
// 注册
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
// 建议在应用退出时解绑(防止静态事件泄漏,尽管进程退出会清理)
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload;
AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;
void OnProcessExit(object sender, EventArgs e) { /* 刷盘、写日志 */ }
void OnDomainUnload(object sender, EventArgs e) { /* 释放域内资源 */ }
void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
// 记录致命异常;e.IsTerminating 表示是否即将终止
}
三、常用属性
- BaseDirectory:探测程序集的基础目录(AppDomainSetup.ApplicationBase)。用于确定加载路径。
- RelativeSearchPath:相对探测路径(私有路径,强名称程序集不会从这里加载)。
- ShadowCopyFiles:是否启用影子复制(避免锁定文件)。
- FriendlyName:域的友好名(默认域通常为可执行文件名)。
- Id:域标识。
- IsFullyTrusted:域是否完全信任(CAS 相关;.NET Framework 桌面应用通常为 true)。
- MonitoringIsEnabled(4.5+):启用域级监控(需显式开启)。配套:
- MonitoringTotalAllocatedMemorySize / MonitoringTotalProcessorTime:域内分配内存与处理器时间。
- SetupInformation:AppDomainSetup(包含 ApplicationBase、ConfigurationFile、PrivateBinPath 等)。
示例读取:
var d = AppDomain.CurrentDomain;
string baseDir = d.BaseDirectory;
string relPath = d.RelativeSearchPath;
bool shadowCopy = d.ShadowCopyFiles == "true";
string name = d.FriendlyName;
bool trusted = d.IsFullyTrusted;
四、常用方法与数据存取
- GetAssemblies():获取当前域已加载的程序集列表。
- Load(AssemblyName)/Load(string):加载程序集(不建议随意使用 string 版本)。
- CreateDomain(name, evidence, setup):创建新域(隔离执行;桌面应用较少用)。
- ExecuteAssembly(path, args):在域中执行程序集入口点。
- SetData/GetData(name, value):域级键值存储(跨线程共享,域内有效)。
- DoCallBack(CrossAppDomainDelegate):在目标域执行委托(跨域场景)。
- SetPrincipalPolicy / SetThreadPrincipal:设置域默认主体策略(安全/身份相关)。
示例(域级数据):
AppDomain.CurrentDomain.SetData("MyKey", "MyValue");
var v = AppDomain.CurrentDomain.GetData("MyKey") as string;
五、程序集解析(AssemblyResolve)典型用法
- 目标:当 CLR 无法在既定探测路径找到程序集时,你可以提供加载逻辑(例如从自定义目录或嵌入资源解压再加载)。
- 注意:仅在解析失败时触发;返回 Assembly 实例。避免死循环。
示例(简化):
AppDomain.CurrentDomain.AssemblyResolve += (s, args) =>
{
var an = new System.Reflection.AssemblyName(args.Name);
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libs", an.Name + ".dll");
return System.IO.File.Exists(path) ? System.Reflection.Assembly.LoadFrom(path) : null;
};
六、与 WPF/桌面程序的搭配建议
- 异常处理:
- WPF 主线程 UI 异常:Application.Current.DispatcherUnhandledException(更适合更新 UI 或提示)。
- 域级/后台线程异常兜底:AppDomain.CurrentDomain.UnhandledException(做最终日志与崩溃上报)。
- 退出与资源回收:ProcessExit/DomainUnload 中做持久化(如用户设置、窗口位置)与遥测上报(注意不要做长耗时)。
- 程序集解析:如你将插件/扩展放在子目录,用 AssemblyResolve 提供路径。
- 性能监控(4.5+):可以在启动时开启 MonitoringIsEnabled 用于域级统计(开销小,但仍建议评估)。
七、限制与陷阱
- UnhandledException 并非全能:
- 无法处理 StackOverflowException、AccessViolation、OutOfMemory 等某些致命崩溃。
- 事件触发后通常进程将终止(e.IsTerminating=true),不要尝试复杂恢复。
- AssemblyResolve 仅在解析失败时触发,且返回错误会导致加载失败;避免在事件里做重型 IO 或网络。
- 影子复制 ShadowCopyFiles 多用于 ASP.NET/服务端;桌面应用启用的价值有限。
- 多域复杂度高:跨域对象需 MarshalByRefObject 或可序列化;WPF 桌面通常不建议引入多域架构。
- FirstChanceException 量大:仅用于调试或诊断,生产环境慎用以免日志爆量。
结论
- AppDomain.CurrentDomain 是桌面应用的“域级生命周期与解析/异常枢纽”。在 WPF 中,配合 DispatcherUnhandledException 处理 UI 异常,使用 ProcessExit/DomainUnload 做收尾,按需使用 AssemblyResolve 做插件加载,就能覆盖绝大多数应用级场景。
了解更多
System.Windows.Controls 命名空间 | Microsoft Learn
控件库 - WPF .NET Framework | Microsoft Learn
使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn
HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频
更多推荐


所有评论(0)