最近需要通过WMI监控远程服务器的CPU状况,于是使用了WMI轮询服务器的CPU情况,并显示在DevExpress的Gauges控件。
程序运行正常,但过了1个甚至几个小时,会莫名出现如下异常:
2009-10-30 12:14:54,409 [5572] WARN - System.Runtime.InteropServices.COMException (0x800706BF)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
at System.Management.ManagementObjectCollection.get_Count()
at MorningStar.Blade.ProcessMonitorUtil.Win32ServiceManager.GetObjects(String queryString, Boolean allowQueryCaching) in ****.Blade.ProcessMonitorUtil\Utils\Win32ServiceManager.cs:line 288
因服务器的CPU监控至少有一个小时以上是正常的,所以我们认为WMI在权限和配置是“正常”的,于是先采用如下方式进行处理(WMI的配置到处都是,此文就不贴那么多代码了):

GetObjects
1
private ManagementObjectCollection GetManagementObjectCollection(string queryString)
2
{
3
ManagementObjectCollection result = null;
4
ObjectQuery query = new ObjectQuery(queryString);
5
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(this.managementClass.Scope, query))
6
{
7
result = searcher.Get();
8
}
9
return result;
10
}
11
public ManagementObjectCollection GetObjectCollection(string queryString, bool allowQueryCaching)
12
{
13
ManagementObjectCollection result = null;
14
if (allowQueryCaching) QueryCache.TryGetValue(queryString, out result);
15
if (result == null)
16
{
17
result = GetManagementObjectCollection(queryString);
18
if (allowQueryCaching)
19
{
20
if (QueryCache.ContainsKey(queryString)) QueryCache[queryString] = result;
21
else QueryCache.Add(queryString, result);
22
}
23
}
24
return result;
25
}
26
public ManagementObject[] GetObjects(string queryString, bool allowQueryCaching)
27
{
28
ManagementObject[] result = new ManagementObject[0];
29
try
30
{
31
ManagementObjectCollection collection = GetObjectCollection(queryString, allowQueryCaching);
32
if (collection != null && collection.Count > 0)
33
{
34
result = new ManagementObject[collection.Count];
35
collection.CopyTo(result, 0);
36
}
37
}
38
//If Exception happened,then re-connect,and invoke itself
39
catch (Exception ex)
40
{
41
this.managementClass.Scope.Connect();
42
GetObjects(queryString, allowQueryCaching);
43
}
44
return result;
45
}
经过调试,大致经过一个半小时后,出现异常,经过两次重试后,可再次获取数据。
不过这种做法是特殊处理,大概也就是特殊情况特殊对待吧