尽管可能很奇怪,但似乎只有当您不对搜索结果执行任何操作时才会发生内存泄漏。将问题中的代码修改如下不会泄漏任何内存:
using (var src = mySearcher.FindAll())
{
var enumerator = src.GetEnumerator();
enumerator.MoveNext();
}
这似乎是由具有延迟初始化的内部 searchObject 字段引起的,用 Reflector 查看 SearchResultCollection :
internal UnsafeNativeMethods.IDirectorySearch SearchObject
{
get
{
if (this.searchObject == null)
{
this.searchObject = (UnsafeNativeMethods.IDirectorySearch) this.rootEntry.AdsObject;
}
return this.searchObject;
}
}
除非初始化了 searchObject,否则 dispose 不会关闭非托管句柄。
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (((this.handle != IntPtr.Zero) && (this.searchObject != null)) && disposing)
{
this.searchObject.CloseSearchHandle(this.handle);
this.handle = IntPtr.Zero;
}
..
}
}
对 ResultsEnumerator 调用 MoveNext 会调用集合上的 SearchObject,从而确保它也得到正确处理。
public bool MoveNext()
{
..
int firstRow = this.results.SearchObject.GetFirstRow(this.results.Handle);
..
}
我的应用程序中的泄漏是由于其他一些非托管缓冲区未正确释放而导致的,并且我所做的测试具有误导性。现在问题已解决。