调用Close()后仍可访问Registry基键对象,此行为是否符合预期?
RegistryKey.Close() 行为疑问解答
结论:该行为符合.NET Framework 4.8的设计预期
你观察到的现象本质是:RegistryKey.Close()方法的作用是释放对象持有的底层Win32注册表句柄,而非销毁托管对象本身。
- 托管对象(比如
baseKey)在调用Close()后,依然存在于内存中,直到被垃圾回收器(GC)回收。 - 当你调用已关闭的
baseKey的OpenSubKey()方法时,.NET内部会重新向系统申请新的注册表句柄,因此这个调用能够成功执行。 - 而子键
key调用Close()后,其底层句柄被释放,此时如果再调用GetValue()这类依赖句柄的方法,理论上会抛出ObjectDisposedException(你测试中“子键已被释放”的描述对应这类不可用状态)。
文档中“调用Close()应销毁对象”的表述容易产生误解,实际它指的是销毁(释放)非托管资源,而非托管对象本身。托管对象的生命周期由GC完全管理,开发者无法通过方法调用直接销毁托管对象。
推荐实践
为了避免资源泄漏和这类行为带来的混淆,建议使用using语句自动管理RegistryKey的资源,它会在代码块结束时自动调用Close():
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)) { using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true)) { var testValue = key.GetValue("TestNameInWinlogon"); } using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows", true)) { var testValue = key.GetValue("TestNameInWindows"); } }
内容的提问来源于stack exchange,提问作者Beegaran_abu
相关产品推荐
相关产品推荐

