2010-08-26 6 views
4

В настоящее время я пишу кусок кода, который делает некоторые запросы, которые возвращают объекты IDisposable (DirectoryEntry быть конкретными из экземпляра ADAM) и я в конечном итоге с кодом похож наLINQ запрос и IDisposable

using(var entry = (from result in results 
        let entry = result.GetDirectoryEntry() 
        where entry != null 
        select entry).Last()) 
{ 
    //blah blah 
} 

но кто затем отвечает за удаление объектов, не возвращенных вышеуказанным запросом? или более, - это выше код, фактически отсутствующий вызов Dispose() для всех других записей, чем последний?

ответ

3

если это Линк для объектов, то вы несете ответственность. Да, объекты не будут удалены. Вы должны выполнить результаты запроса до Last и Dispose их вручную.

+0

Я никогда не видел примера кода, который налагает физические объекты Linq. Сборщик мусора в конечном итоге очищает объекты, и если у вас нет чего-то вроде долговременного неуправляемого процесса по запросу Linq, ручное удаление не требуется. –

+2

Только если код действительно реализует финализатор. Если не будет реализован финализатор, тогда ресурсы будут действительно течь. Не говоря уже о том, что это приводит к: а) Ресурсам, не находящимся в состоянии ASAP, и б) Продвижению объектов в более длинную очередь сбора мусора, которая может иметь влияние на производительность, если вы выделяете и уничтожаете множество объектов с помощью финализаторов. – Spence

+1

Хороший избавитель должен выполнить свою работу, а затем вызвать GC.SuppressFinalize (this); – Spence

1

Утилизация основана на контексте данных. Сам запрос является чистым .Net и не требует удаления, если вы не создадите объекты, которые требуют утилизации. В этом случае вам нужно будет индивидуально вызвать устройство удаления на всех объектах, которые вы вызываете.

Я не думаю, что использование linq в этой ситуации будет подходящим, поскольку вы собираетесь утечки ресурсов. AFAIK они работают с linq для активного поставщика каталогов, но до тех пор вам, вероятно, будет лучше попытаться написать ваш запрос непосредственно в AD.

Или вы можете написать цикл, чтобы иметь дело с ресурсами:

DirectoryEntry entry = null; 
foreach(var result in results) 
{ 
    //Need to add logic to deal with errors. 
    var temp = result.GetDirectoryEntry(); 
    if (temp != null) 
    { 
     if (entry != null) 
     { 
      entry.Dispose(); 
      entry = temp; 
     } 
     else 
     { 
      entry = temp; 
     } 
    } 
} 
using (entry) 
{ 
    //code here 
} 

BTW вы должны увидеть эту запись под MSDN GetDirectoryEntry: Вызов GetDirectoryEntry на каждом SEARCHRESULT возвращается через DirectorySearcher может быть медленным.

Смежные вопросы