我有一个返回远程机器上的服务列表的方法。我使用ManagementObjectSearcher.Get()和WIN32查询获取ManagementObjectCollection。然后在foreach循环中创建我的Service类的实例并将其添加到结果列表中。在初始化新服务时,我使用GetPropertyValue(字符串)获取ManagementObject属性。我面临的问题是这个过程非常缓慢。我认为GetPropertyValue很慢(我每次循环使用它7次)。是否有更快的方法从ManagementObject类获取属性?
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);}
答案 0 :(得分:1)
我一直在与此作斗争,试图了解什么是如此缓慢。
我编写了一个测试程序,几乎所有东西都使用了秒表时间。 我有一个从Win32_PnPSignedDriver返回3个设备的wql查询。 我使用了三种不同的方法从查询中检索结果。
ManagementObjectCollection queryResults;
ManagementObjectSearcher searcher = new ManagementObjectSearcher();
var myWql = "SELECT * FROM Win32_PnPSignedDriver WHERE ..."
searcher.Scope = new ManagementScope(@"root\CIMV2");
searcher.Query = new WqlObjectQuery(wmiQry);
queryResults = searcher.Get();
searcher.Get()很快。
我使用三种方法从ManagementObjectCollection queryResults中检索数据。
首次测试: 方法1:非常慢 - 超过3000执行空循环。 方法2:非常快。 1毫秒 方法3:也非常快。 0毫秒。
然后我在测试中看到了错误。第一个循环计算了集合中的对象,然后框架记住了这一点。如果我多次执行方法1,只有初始循环很慢,但是重复foreach是0到1毫秒。
我重构了我的测试,在每次获取数据之前重新执行查询。 方法1:每次都很慢。 方法2:每次都慢。 方法3:我的秒表计时报告0到1毫秒,但我注意到执行时间更长。 ???
深入研究我编码的内容,我看到我没有计算以下内容:
ManagementObject[] deviceArray = new ManagementObject[queryResults.Count];
实际上是两个命令:
var count = queryResults.Count;
ManagementObject[] deviceArray = new ManagementObject[count];
我分别计时,看到queryResults.Count几乎一直占用。经常> 3000毫秒。
然后我硬编码了数组的大小以避免调用:queryResults.Count
然而,当我执行
时queryResults.CopyTo(deviceArray, 0);
CopyTo方法仍然需要知道ManagementObjectCollection中有多少项,现在CopyTo采用>之前为0或1毫秒的3000毫秒。
所以,它会出现ManagementObjectCollection。 get_Count是瓶颈,我无论如何都不知道检索结果而不会导致执行Count getter。