2015-09-22 4 views
1

Я работаю с элементами ManagementObjects и foreach в C#. Coverity заявляет, что существует утечка в коде, подобном этому:Реальная утечка ресурсов для объекта foreach реального или ложного срабатывания?

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

Это настоящая утечка или ложный положительный результат?

Используется ли этот блок (здесь была моя первоначальная попытка избежать утечки)?

Я думаю, что это управляемая коллекция, которая реализует IDisposable, и вызывающий не должен нести ответственность за ее уничтожение. Я видел следующий код предложил прежде, но это, кажется, как она идет по неверному пути с более использованием блоков:

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

Ну, молитесь, не переставали жаловаться, когда вы исправили свой код? –

+0

@HansPassant Вышеупомянутый код - это то, о чем жалуется Coverity. Я не думаю, что там есть утечка, но я не уверен. Пример MSDN, который я нашел, не имеет каких-либо блоков ([link] (https://msdn.microsoft.com/en-us/library/ms186146 (VS.80) .aspx)). Я склонен изменить код, чтобы более точно походить на этот пример, но хочу сделать домашнее задание по этой проблеме. Прямо сейчас у меня около 48-часовой задержки, прежде чем я смогу получить обновленные результаты Покрытия по разным причинам. – PerryC

ответ

1

ManagementObject является одноразовым и не расположены в этом коде. Вот что такое предупреждение. Это настоящий позитив.

Класс сбора (mySearcher.Get()) также не используется, но он должен быть. Обложка должна предупредить об этом.

Я сделал очень мало WMI до сих пор, но кажется, что почти все должно быть утилизировано. Отвратительный API. Win32 сияет.

Если это броская программа, я бы просто не переживала ни о чем. В противном случае вам, вероятно, придется распоряжаться.

+0

Я понимаю, что mySearcher.Get() возвращает ManagementObjectCollection, который наследует от ICollection, IEnumerable и IDisposable. Основываясь на этом SO post [link] (http://stackoverflow.com/questions/4982396/does-foreach-automatically-call-dispose) и моих исследованиях, foreach должен избавиться от ManagementObjectCollection уже, правильно? – PerryC

+1

foreach предоставляет перечислитель, а не перечислимый. Если бы это было так, что бы все могло убить его! – usr

+0

Итак, каждый элемент ManagementObject обновляется где-то в итераторе и требует явного вызова Dispose (или обертывания в блоке using)? – PerryC