最近需要通过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的配置到处都是,此文就不贴那么多代码了):
1private 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 }
经过调试,大致经过一个半小时后,出现异常,经过两次重试后,可再次获取数据。
不过这种做法是特殊处理,大概也就是特殊情况特殊对待吧