Fastest way of getting properties of ManagementObject
I have a method that returns list of services on remote machine. I'm getting the ManagementObjectCollection using ManagementObjectSearcher.Get() and WIN32 query. Then in foreach loop I'm creating instance of my Service class and add it to result List. While initializing new Service I'm getting ManagementObject properties using GetPropertyValue(string). The problem i'm facing is that this process is very slow. I think that GetPropertyValue is slow(I'm using it 7 times per loop). Is there faster way of getting properties from ManagementObject class?
var query = new ObjectQuery("Select Name, DisplayName, ProcessId, Description, State, StartMode, StartName From Win32_Service");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection allServices = searcher.Get();
foreach (ManagementObject p in allServices)
{Service newService = new Service{ Name = p.GetPropertyValue("Name"),etc...} result.Add(newService);}
I have been fighting with this, trying to understand what is so slow.
I write a test program, and used Stopwatch time practically everything. I have a wql query that returns 3 devices from Win32_PnPSignedDriver. I used three different methods to retrieve the results from the query.
ManagementObjectCollection queryResults;
ManagementObjectSearcher searcher = new ManagementObjectSearcher();
var myWql = "SELECT * FROM Win32_PnPSignedDriver WHERE ..."
searcher.Scope = new ManagementScope(@"rootCIMV2");
searcher.Query = new WqlObjectQuery(wmiQry);
queryResults = searcher.Get();
searcher.Get() is plenty fast.
I use three methods of retrieving data from ManagementObjectCollection queryResults.
First testing: Method 1: Was very slow -- over 3000 to execute an empty loop. Method 2: Was very fast. 1 ms Method 3: Also very fast. 0 ms.
Then I saw the fault in my testing. The first loop counted the object in the collection, and then this was remembered by the framework. If I executed Method 1 several times, only the initial loop was slow, but then repeating the foreach was 0 to 1 ms.
I restructured my test to re-execute the query before each fetch of the data. Method 1: Was slow every time. Method 2: Also slow every time. Method 3: My Stopwatch timing reported 0 to 1 ms, but I noticed the execution time was much longer. ???
Looking deeply into what I coded, I saw that I did not time the following line:
ManagementObject[] deviceArray = new ManagementObject[queryResults.Count];
Which is actually two commands:
var count = queryResults.Count;
ManagementObject[] deviceArray = new ManagementObject[count];
I timed each separately, and saw that the queryResults.Count took almost all the time. Often > 3000 ms.
I then hardcoded the size of the array to avoid the call: queryResults.Count
However, when I executed
queryResults.CopyTo(deviceArray, 0);
The CopyTo method still needed to know how many items are in the ManagementObjectCollection, and now the CopyTo took > 3000 ms where it had been 0 or 1 ms before.
So, it would appear that ManagementObjectCollection. get_Count is the bottleneck, and I do not know anyway to retrieve the results without causing the Count getter to be executed.
链接地址: http://www.djcxy.com/p/19202.html上一篇: 在单周期数据路径中加载半字和加载字节