在 foreach-object 之后处理 SearchResultCollection

Dispose of SearchResultCollection after foreach-object

根据 MSDN 的说明,.Dispose() 必须在完成后在 System.DirectoryServices.SearchResultCollection 上调用。

Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.

我也在读到您应该使用 Foreach-Object 而不是 foreach 来节省内存,因为 foreach 需要将整个 SearchResultCollection 保存到内存才能被迭代。

$objSearcher.FindAll() | Foreach-Object { $_ }

优于

$objResults = $objSearcher.FindAll()
foreach($objResult in $objResults)
{
    $objResult
}

我想不通的是如果你使用 Foreach-Object 如何调用 .Dispose()?

foreach 语言语句不等同于 ForEach-Object cmdlet,尽管它们具有相似的用途。 (不幸的是,ForEach-Object 有一个默认别名 foreach,IMO 只会增加混乱。)

我的建议是在迭代目录搜索结果时不要使用 ForEach-Object,因为 DirectorySearcher 是高效的并且不需要 ForEach-Object。 (我还建议将 Write-Progress 作为迭代的一部分,因为 DirectorySearcher 可能 return 是一个长列表。)

ForEach-Object 在您需要 PowerShell 的流式处理行为并且您可能没有高效搜索时很有用。

比尔·斯图尔特是对的。 .FindAll() returns 一个 IEnumerable 所以你选择哪个并不重要。

但是对于如何使用 ForEach-Object 对象 Dispose 的问题,由于上述原因,您可以像使用 foreach 一样先将其存储在变量中,然后管道:

$objResults = $objSearcher.FindAll()
$objResults | Foreach-Object { $_ }
$objResults.Dispose()