开发者

.Net WMI classes - which ones do I have to dispose?

开发者 https://www.devze.com 2023-03-18 23:23 出处:网络
If I am using a ManagementObjectSearcher, I can easily wrap it in a using block: using (var searcher = new ManagementObjectSearcher(scope, query))

If I am using a ManagementObjectSearcher, I can easily wrap it in a using block:

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

It is also easy to dispose the collection returned from the searcher, due to the fact that foreach automatically calls dispose on the enumerator:

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

But ManagementObject also implements开发者_开发问答 IDisposable:

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

        mo.Dispose(); // ?
    }
}
  • Do I have to dispose each ManagementObject instance returned in this scenario?
  • If I do, how do I make it exception safe?
  • Is there a way I can still use Linq in this scenario (and still properly call Dispose)? Especially with constructions like searcher.Get().First()?

Edit: A few more related questions:

  • Do I also have to call Dispose on the search result collection?
  • How about the searcher?

They both also implement their own IDisposable method, though it seems like the searcher only inherits the Dispose implementation from Component; it doesn't add its own dispose behavior.


ManagementObject inherits from System.ComponentModel.Component and you should call Dispose explicitly for all inherited from Component objects. You can use LINQ methods with your own predicates which invokes Dispose itself:

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

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

                    return result;
                });

This code is equivalent to:

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");
}

Where Satisfy is your own method.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号