C# - 多个服务器的WMI查询太慢

时间:2012-08-01 14:56:46

标签: c# multithreading windows-server-2008 wmi

我正在尝试从远程win2008服务器返回所有启用的功能。这根本不是什么问题 - 只要我知道究竟要查询什么。

我遇到的问题是,当我的查询没有找到结果时,需要永久验证是否安装了该功能 - 有时长达2分钟。 (查询超过600个节点时不够好。)

以下代码是我发现的最快的方式,但正如我所说:返回false需要永远:

 public bool serverFeatureEnabled(string machineName, Win32_ServerFeature_ID id)
    {
        ManagementClass serviceClass = new ManagementClass("Win32_ServerFeature");
        string strScope = string.Format(@"\\{0}\root\cimv2", machineName);
        ConnectionOptions conOpt = new ConnectionOptions();
        serviceClass.Scope = new ManagementScope(strScope, conOpt);

        foreach (ManagementObject obj in serviceClass.GetInstances())
        {
            if ((UInt32)obj["ID"] == (uint)id)
            {
                return true;
            }

        }
        return false;
    }

有没有人有更好的想法,我不介意它根本不使用WMI查询。

我想做的就是加快速度。

我希望我有道理!

感谢任何帮助。

修改:

我曾试图“按照Sergrey V的建议,直接从使用ManagementObjectSearcher类的服务器功能中选择所需的功能”。

它确实加快了第一次错误的返回,但是完成所需的时间大约需要14秒,所有这些都会在集群中查询的所有服务器的140分钟内增加upp。

编辑2:

我尝试使用WBEMTEST(Windows Management Instrumentation Tester)对Win32_ServerFeature运行测试,与远程计算机的连接似乎是问题 - 对其中一台远程计算机运行测试大约需要12秒才能连接,大约2秒钟返回数据。

因此,Sergrey V提出的解决方案似乎是迄今为止WMI查询的最快解决方案。

4 个答案:

答案 0 :(得分:2)

尝试使用ManagementObjectSearcher类从服务器功能中直接选择所需的功能:

            string serverName = "serverName";
            string className = "Win32_ServerFeature";
            string propertyName = "ID";
            int propertyValue = 144;
            string query = string.Format("SELECT * FROM {0} WHERE {1} = {2}", className, propertyName, propertyValue);
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            string scopePath = string.Format(@"\\{0}\root\cimv2", serverName);
            searcher.Scope = new ManagementScope(string.Format(scopePath));
            ManagementObjectCollection mCollection = searcher.Get();

            bool featureEnabled = mCollection.Count > 0;

答案 1 :(得分:2)

不要连续运行动作。我不知道WMI内部是否存在瓶颈,但最明显的优化是并行运行整个事物。

答案 2 :(得分:1)

所以这就是我最终做的事情:  首先,正如M Afifi所提出的,我为列表中的每个节点启动了一项新任务。 然后使用'Task.Factory.StartNew()'并行执行WMI查询。 (使用System.Threading.Tasks;)

列表中所有节点的完全执行现在大约需要12秒!

 referenceList.connectionNodes().ForEach(x =>
            {
                var genericTask = Task.Factory.StartNew(() =>
                    {
                        regkeyFactory.testParallelExecution(x);
                    });
            });

谢谢你们的帮助!

答案 3 :(得分:-1)

更快的方法是扫描一体机,我使用ManagementClass制作了一个HWID类,只需要0.07秒即可获得机器的唯一硬件ID

相关问题