Как сделать WMI-запросы только для чтения и только для чтения в C#?

Мне сказали коллеги, что, если мои запросы сбора информации о системе WMI предназначены только для пересылки и / или только для чтения, они будут выполняться намного быстрее. В этом есть смысл. Но как мне это сделать?

2 ответа

Решение

Вам необходимо использовать класс 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"]);
            }
            */
        }
    }
}

Вы не увидите никакого улучшения производительности, если не будете использовать его для перечисления класса с большим количеством экземпляров (например, Cim_DataFile), и вы получите возможность перечислять возвращенную ManagementObjectCollection только один раз. Вы также не сможете использовать ManagementObjectCollection.Count и т. Д. Что касается запросов только для чтения, я не уверен, как их создавать.

Ваш коллега должен был использовать полусинхронные вызовы методов вместе с перечислителями только для пересылки. В полусинхронном режиме вызовы методов WMI немедленно возвращаются, а объекты извлекаются в фоновом режиме и возвращаются по запросу после их создания. Кроме того, при использовании полусинхронного режима для извлечения большого количества экземпляров рекомендуется получить перечислители только для пересылки, чтобы повысить производительность. Эти особенности объясняются в этой статье MSDN.

Как отметил Урос, чтобы получить перечислитель только для пересылки в полусинхронном режиме, вам необходимо использовать EnumerationOptions экземпляр класса с ReturnImmediately свойство установлено в true и Rewindable свойство установлено в falseНапример:

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

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, opt);
Другие вопросы по тегам