Как сделать 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);