How to make forward-only, read-only WMI queries in

2019-06-28 02:01发布

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?

标签: c# .net wmi
2条回答
干净又极端
2楼-- · 2019-06-28 03:04

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

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.

查看更多
戒情不戒烟
3楼-- · 2019-06-28 03:05

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.

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.:

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

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, opt);
查看更多
登录 后发表回答