.Net WMI классы - какие из них я должен располагать? - PullRequest
8 голосов
/ 10 июля 2011

Если я использую ManagementObjectSearcher, я могу легко обернуть его в using блок:

using (var searcher = new ManagementObjectSearcher(scope, query))
{
    // ...
}

Также легко распоряжаться коллекциейвозвращается из поисковика из-за того, что foreach автоматически вызывает распоряжение на счетчике :

using (var searcher = new ManagementObjectSearcher(scope, query))
{
    foreach(ManagementObject mo in searcher.Get())
    {
        // ...
    }
}

Но ManagementObject также реализует IDisposable:

using (var searcher = new ManagementObjectSearcher(scope, query))
{
    foreach(ManagementObject mo in searcher.Get())
    {
        // ...

        mo.Dispose(); // ?
    }
}
  • Нужно ли распоряжаться каждым экземпляром ManagementObject, возвращенным в этом сценарии?
  • Если я это сделаю, как сделать это исключение безопасным?
  • есть ли способ, которым я все еще могу использовать Linq в этом сценарии (и все равно правильно вызывать Dispose)?Особенно с такими конструкциями, как searcher.Get().First()?

Редактировать : Еще несколько связанных вопросов:

  • Должен ли я также позвонить Dispose наколлекция результатов поиска?
  • Как насчет поисковика?

Они оба также реализуют свой собственный метод IDisposable, хотя кажется, что поисковик наследует только реализацию Dispose отComponent;он не добавляет своего собственного поведения удаления.

1 Ответ

3 голосов
/ 10 июля 2011

ManagementObject наследуется от System.ComponentModel.Component и . Вы должны явно Dispose вызвать для всех унаследованных от Component объектов.Вы можете использовать LINQ методы со своими собственными предикатами, которые сами вызывают Dispose:

var first = searcher.Get().First(x =>
                {
                    bool result = Satisfy(x);

                    if (!result)
                    {
                        x.Dispose();
                    }

                    return result;
                });

Этот код эквивалентен:

ManagementObject first = null;

foreach (var element in searcher.Get())
{
    if (Satisfy(element))
    {
        first = element;
        break;
    }
    else
    {
        element.Dispose();    
    }
}

if (first == null)
{
    throw new InvalidOperationException("No match");
}

Где Satisfy - ваш собственный метод.

...