【问题标题】:.Net WMI classes - which ones do I have to dispose?.Net WMI 类 - 我必须处理哪些?
【发布时间】:2011-07-10 05:43:13
【问题描述】:

如果我使用的是ManagementObjectSearcher,我可以轻松地将其包装在using 块中:

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

处理the collection returned from the searcher也很容易,因为foreach automatically calls dispose on the enumerator

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 方法,尽管搜索器似乎只从Component 继承了Dispose 实现;它不会添加自己的处置行为。

【问题讨论】:

    标签: c# linq wmi idisposable


    【解决方案1】:

    ManagementObject 继承自 System.ComponentModel.Componentyou should call Dispose explicitly,所有继承自 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 是你自己的方法。

    【讨论】:

    • 很抱歉,在您回答之后,我的问题变得臃肿。请查看我的编辑。你提到了底部的措辞,说你应该总是在从Component派生的类上调用Dispose。但是,对于一个没有添加任何自己的 Dispose 实现的类,有什么理由这样做吗?我从 Reflector 中看到 Component 上的 Dispose 的内部有一些有趣的东西,但它似乎只适用于我在某种“站点”上下文中使用它的情况。我不知道这是否适用于这种情况......
    • 检查过,Site 似乎为空。我没有绑定到 on-Dispose 事件,所以在这种情况下它看起来真的不会做任何事情。但我会很感激你的两分钱。
    • 我认为以下框架开发人员的建议是一个很好的做法。真的,您不应该使用反射器或其他任何东西来对这个版本的代码的工作方式做出任何假设或假设。在 MSDN 中,Microsoft 写道,您必须为从 Component 继承的每个对象调用 Dispose。如果你不这样做,你可能会在一些复杂的用例或框架的其他版本中遇到问题。忽略规范是导致应用程序在新版本的操作系统或框架中失败的第一件事。
    • 好点。无论如何,我会将它全部包装在扩展方法中:)
    猜你喜欢
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2011-10-26
    • 2016-11-21
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多