找不到这个MSDN文档中的任何东西。
即是它足够的做,说:
using(PrincipalSearcher searcher = ...)
{
foreach (var principal in searcher.FindAll())
{
... do something ...
} // The PrincipalSearchResult<T> returned by searcher.FindAll is disposed here
}
这是大多数的例子我见过呢,还是我应该做的:
using(PrincipalSearcher searcher = ...)
{
foreach(var principal in searcher.FindAll())
{
using (principal)
{
// ... do something ...
}
}
}
后者(明确处置迭代过程中每个项目)看起来“更安全” - 即符合指引,明确处置的所有IDisposable的对象 - 但它是一个有点乱; 例如,它排除了使用LINQ的遍历搜索结果。
为了响应@ RUP的评论:
你可以写从父迭代器返回一个结果的迭代器产量
是的,我认为这工作,使LINQ。 类似下面的扩展方法:
public static IEnumerable<T> EnumerateAndDispose<T>(this IEnumerable<T> collection) where T : IDisposable
{
foreach (T item in collection)
{
using (item)
{
yield return item;
}
}
}
可以使用的为:
searcher.FindAll().EnumerateAndDispose().Select(... use LINQ ...)
但是,有必要吗?
一般来说speacking,在许多情况下,不调用Dispose()不会造成大问题:良好的书面一次性对象将实行清理东西的终结需要相同的逻辑。 (免责声明:我不是说“不叫处理”:这是有原因的。例如,定稿会发生很多后来我只描述什么是这里的后果)。
然而,AD对象是一个显着的例外; 特别是, SearchResultCollection
是著名的从这个问题的痛苦(参考:MSDN(类文档都和其他物品),以及Active Directory的:设计,部署和运行Active Directory )。 看来,由于技术原因,不可能以释放其终结的资源,所以不调用dispose会导致内存泄漏。
正如斯科特和乔指出,很多MSDN示例不调用Dispose集合中的物品; 不过,瑞恩·邓恩,前Windows Azure的技术专家和在.NET开发人员指南目录服务编程的合着者,建议使用来调用部署在每个项目上这个博客帖子 。 从帖子:
在一般情况下,始终明确对以下对象类型调用Dispose():
- 的DirectoryEntry
- SearchResultCollection(从.FindAll())
- 的DirectorySearcher(如果你还没有明确设置SearchRoot)
这是你可以有一个“权威人士”最近,我相信; 但是我个人的意见是:
- 如果可以的话,就调用处理。 它不会让任何不好的,特别是如果你能找回LINQ功能与乔的扩展方法
- 去使用反射/ ilspy /反汇编和/或类似的存储配置文件dotTrace真正看到正在发生的事情(基本上,斯科特已经做了,但不断深入)
我最初来到现场问同样的问题,但看到你的问题给了我动力爆发ILSpy ,弄清自己,如果它不这样做。
首先,搜索结果的处置功能:
// System.DirectoryServices.AccountManagement.PrincipalSearchResult<T>
public void Dispose()
{
if (!this.disposed)
{
if (this.resultSet != null)
{
lock (this.resultSet)
{
this.resultSet.Dispose();
}
}
this.disposed = true;
}
}
从那里,我检查resultSet.Dispose()
在我的情况的resultSet是ADDNLinkedAttrSet
)
// System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet
public override void Dispose()
{
try
{
if (!this.disposed)
{
if (this.primaryGroupMembersSearcher != null)
{
this.primaryGroupMembersSearcher.Dispose();
}
if (this.queryMembersResults != null)
{
this.queryMembersResults.Dispose();
}
if (this.currentMembersSearcher != null)
{
this.currentMembersSearcher.Dispose();
}
if (this.memberSearchResults != null)
{
this.memberSearchResults.Dispose();
}
if (this.memberSearchersQueue != null)
{
foreach (DirectorySearcher directorySearcher in this.memberSearchersQueue)
{
directorySearcher.Dispose();
}
this.memberSearchersQueue.Clear();
}
IDisposable disposable = this.members as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
IDisposable disposable2 = this.membersEnum as IDisposable;
if (disposable2 != null)
{
disposable2.Dispose();
}
if (this.membersQueue != null)
{
foreach (IEnumerable enumerable in this.membersQueue)
{
IDisposable disposable3 = enumerable as IDisposable;
if (disposable3 != null)
{
disposable3.Dispose();
}
}
}
if (this.foreignGroups != null)
{
foreach (GroupPrincipal groupPrincipal in this.foreignGroups)
{
groupPrincipal.Dispose();
}
}
this.disposed = true;
}
}
finally
{
base.Dispose();
}
}
你可以看到foreach循环在那里itterating在它拥有的所有成员。 因此,它是做处置你的每个部件上。
所以,是的,它不处理所有成员的,然后一些。