调用Win32_OperatingSystem方法后关闭应用,资源无法立即释放
问题描述
我正在开发一款以学习为主要目的的应用,该应用可ping通企业内的远程PC,当判定远程PC在线时,会拉取部分信息进行展示。目前尝试实现向远程PC发送命令(如重启)的功能,通过Win32_OperatingSystem的Reboot方法实现远程重启后,发现关闭应用时Visual Studio的调试模式仍会持续运行近一分钟,内存也未立即释放。此前应用可立即关闭并释放资源,因此认为代码存在问题,寻求帮助。
当前重启远程工作站的代码:
private void RestartWorkstation_Click(object sender, EventArgs e) { ManagementObjectSearcher searcher = new ManagementObjectSearcher($@"\\{HostName}\root\cimv2", "SELECT * FROM Win32_OperatingSystem"); foreach (ManagementObject mo in searcher.Get()) { mo.InvokeMethod("Reboot", null); MessageBox.Show($"Rebooting {HostName}"); } searcher.Dispose(); }
问题分析与解决方法
问题根源
代码仅手动释放了ManagementObjectSearcher,但遍历searcher.Get()返回的ManagementObject实例未被释放,这些未释放的WMI对象会持有远程连接资源,导致应用关闭时资源无法立即回收,进而出现调试模式卡顿、内存未及时释放的情况。
修复方案
- 用
using语句自动管理资源:ManagementObjectSearcher和ManagementObject都实现了IDisposable接口,using语句会在代码块结束时自动调用Dispose(),确保资源及时释放,比手动调用更可靠,还能避免异常场景下的资源泄漏。 - 优化WMI查询逻辑:
Win32_OperatingSystem在单系统机器上只会返回一个实例,无需遍历所有结果,直接获取第一个实例即可减少不必要的资源占用。
修改后的代码
private void RestartWorkstation_Click(object sender, EventArgs e) { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher($@"\\{HostName}\root\cimv2", "SELECT * FROM Win32_OperatingSystem")) { using (ManagementObjectCollection collection = searcher.Get()) { ManagementObject osInstance = collection.Cast<ManagementObject>().FirstOrDefault(); if (osInstance != null) { using (osInstance) { osInstance.InvokeMethod("Reboot", null); MessageBox.Show($"Rebooting {HostName}"); } } } } }
额外说明
- 若需要确认远程重启结果,可在调用Reboot后添加简短延迟或后续ping检查,但注意不要阻塞UI线程。
- 确保应用运行时拥有足够权限执行远程WMI操作,权限不足也可能引发异常或资源泄漏。
内容的提问来源于stack exchange,提问作者Komodo07
相关产品推荐
相关产品推荐

