【问题标题】:Real ManagementObject foreach loop resource leak or false positive?真正的 ManagementObject foreach 循环资源泄漏或误报?
【发布时间】:2015-09-22 18:24:34
【问题描述】:

我正在使用 C# 中的 ManagementObjects 和 foreach 循环。 Coverity 声称这样的代码存在泄漏:

ObjectQuery myQuery = new ObjectQuery("Select * from Win32_Printer");
using (ManagementObjectSearcher mySearcher = new ManagementObjectSearcher(myQuery))
{
    // alloc_fn: A new resource is returned from allocation method Current.get
    // var_assign: Assigning: mo = resource returned from mo$iterator.Current
    foreach (ManagementObject mo in mySearcher.Get())
    {
        foreach (PropertyData p in mo.Properties)
        {
            // do stuff, maybe return a string
        }
    }
}
// leaked_resource: Returning without closing mo leaks the resource that it refers to
return "";

这是真正的泄漏还是误报?

这里是否需要 using 块(这是我最初避免泄漏的尝试)?

我的想法是,这是一个实现 IDisposable 的托管集合,调用者不应该负责销毁它。我之前看过以下建议的代码,但似乎它正在使用更多 using 块的错误路径:

...
    foreach (ManagementObject mo in mySearcher.Get()) using(mo)
...

【问题讨论】:

  • 好吧,请告诉我,当你修复你的代码时它停止抱怨了吗?
  • @HansPassant 上面的代码是 Coverity 抱怨的。我认为那里实际上没有泄漏,但我不确定。我发现的 MSDN 示例没有任何 using 块 (link)。我倾向于将代码更改为更类似于该示例,但想在这个问题上做我的功课。目前,由于各种原因,我有大约 48 小时的延迟才能获得更新的 Coverity 结果。

标签: c# memory-leaks coverity


【解决方案1】:

ManagementObject 是一次性的,并且不会在该代码中进行处理。这就是警告的内容。这是一个真正的积极因素。

集合类 (mySearcher.Get()) 也没有被释放,但它应该被释放。 Coverity 应该对此发出警告。

到目前为止,我只做了很少的 WMI,但似乎几乎所有东西都需要处理。一个讨厌的 API。 Win32 大放异彩。

如果这是一个扔掉的程序,我根本不会担心它。否则,您可能需要丢弃。

【讨论】:

  • 据我了解,mySearcher.Get() 返回的 ManagementObjectCollection 继承自 ICollection、IEnumerable 和 IDisposable。根据这篇 SO 帖子 link 和我的研究,foreach 应该已经在处理 ManagementObjectCollection 了,对吧?
  • foreach 配置枚举器,而不是枚举器。如果是这样的话,循环遍历任何东西都会杀死它!
  • 所以每个 ManagementObject 都在迭代器的某个地方被更新,并且需要显式调用 Dispose(或包装在 using 块中)?
  • 是的。根据 Reflector 的说法,它似乎没有绑定到您从中获取它的集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 2012-12-07
  • 2014-02-10
  • 1970-01-01
相关资源
最近更新 更多