如何在C#中进行只进,只读的WMI查询?

时间:2022-09-11 17:13:41

I've been told by a coworker that if my WMI system information gathering queries are forward-only and/or read-only, they'll be quite faster. That makes sense. But how do I do it?

一位同事告诉我,如果我的WMI系统信息收集查询只是前向和/或只读,那么它们会更快。那讲得通。但是我该怎么办呢?

2 个解决方案

#1


You need to use EnumerationOptions class and set its Rewindable property to false. Here is an example:

您需要使用EnumerationOptions类并将其Rewindable属性设置为false。这是一个例子:

using System;
using System.Management;

namespace WmiTest
{
    class Program
    {
        static void Main()
        {
            EnumerationOptions options = new EnumerationOptions();
            options.Rewindable = false;
            options.ReturnImmediately = true;

            string query = "Select * From Win32_Process";

            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(@"root\cimv2", query, options);

            ManagementObjectCollection processes = searcher.Get();

            foreach (ManagementObject process in processes)
            {
                Console.WriteLine(process["Name"]);
            }

            // Uncomment any of these
            // and you will get an exception:

            //Console.WriteLine(processes.Count);

            /*
            foreach (ManagementObject process in processes)
            {
                Console.WriteLine(process["Name"]);
            }
            */
        }
    }
}

You won't see any performance improvement unless you use it to enumerate a class with a large number of instances (like Cim_DataFile) and you will get to enumerate the returned ManagementObjectCollection only once. You also won't be able to use ManagementObjectCollection.Count, etc. As for read-only queries, I'm not sure how to make those.

除非您使用它来枚举具有大量实例的类(例如Cim_DataFile),否则您将看不到任何性能改进,并且您将仅枚举返回的ManagementObjectCollection一次。您也将无法使用ManagementObjectCollection.Count等。至于只读查询,我不知道如何制作它们。

#2


Your co-worker must have meant using the semisynchronous method calls together with forward-only enumerators. In the semisynchronous mode, WMI method calls return immediately and objects are retrieved in the background and returned on demand once they are created. Also, when using semisynchronous mode to retrieve a large number of instances, it is recommended to obtain forward-only enumerators to improve the performance. These peculiarities are explained in this MSDN article.

您的同事必须意味着将semisynchronous方法调用与仅向前调查器一起使用。在半同步模式下,WMI方法调用立即返回,并在后台检索对象,并在创建后按需返回。此外,当使用半同步模式检索大量实例时,建议获取仅向前的枚举器以提高性能。这篇MSDN文章解释了这些特性。

As Uros has pointed out, to get a forward-only enumerator in semisynchronous mode, you need to use the EnumerationOptions class instance with the ReturnImmediately property set to true and the Rewindable property set to false, e.g.:

正如Uros所指出的,要在半同步模式下获得仅向前的枚举器,您需要使用EnumerationOptions类实例,并将ReturnImmediately属性设置为true,并将Rewindable属性设置为false,例如:

EnumerationOptions opt = new EnumerationOptions();
opt.ReturnImmediately = true;
opt.Rewindable = false;

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, opt);

#1


You need to use EnumerationOptions class and set its Rewindable property to false. Here is an example:

您需要使用EnumerationOptions类并将其Rewindable属性设置为false。这是一个例子:

using System;
using System.Management;

namespace WmiTest
{
    class Program
    {
        static void Main()
        {
            EnumerationOptions options = new EnumerationOptions();
            options.Rewindable = false;
            options.ReturnImmediately = true;

            string query = "Select * From Win32_Process";

            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(@"root\cimv2", query, options);

            ManagementObjectCollection processes = searcher.Get();

            foreach (ManagementObject process in processes)
            {
                Console.WriteLine(process["Name"]);
            }

            // Uncomment any of these
            // and you will get an exception:

            //Console.WriteLine(processes.Count);

            /*
            foreach (ManagementObject process in processes)
            {
                Console.WriteLine(process["Name"]);
            }
            */
        }
    }
}

You won't see any performance improvement unless you use it to enumerate a class with a large number of instances (like Cim_DataFile) and you will get to enumerate the returned ManagementObjectCollection only once. You also won't be able to use ManagementObjectCollection.Count, etc. As for read-only queries, I'm not sure how to make those.

除非您使用它来枚举具有大量实例的类(例如Cim_DataFile),否则您将看不到任何性能改进,并且您将仅枚举返回的ManagementObjectCollection一次。您也将无法使用ManagementObjectCollection.Count等。至于只读查询,我不知道如何制作它们。

#2


Your co-worker must have meant using the semisynchronous method calls together with forward-only enumerators. In the semisynchronous mode, WMI method calls return immediately and objects are retrieved in the background and returned on demand once they are created. Also, when using semisynchronous mode to retrieve a large number of instances, it is recommended to obtain forward-only enumerators to improve the performance. These peculiarities are explained in this MSDN article.

您的同事必须意味着将semisynchronous方法调用与仅向前调查器一起使用。在半同步模式下,WMI方法调用立即返回,并在后台检索对象,并在创建后按需返回。此外,当使用半同步模式检索大量实例时,建议获取仅向前的枚举器以提高性能。这篇MSDN文章解释了这些特性。

As Uros has pointed out, to get a forward-only enumerator in semisynchronous mode, you need to use the EnumerationOptions class instance with the ReturnImmediately property set to true and the Rewindable property set to false, e.g.:

正如Uros所指出的,要在半同步模式下获得仅向前的枚举器,您需要使用EnumerationOptions类实例,并将ReturnImmediately属性设置为true,并将Rewindable属性设置为false,例如:

EnumerationOptions opt = new EnumerationOptions();
opt.ReturnImmediately = true;
opt.Rewindable = false;

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, opt);