【问题标题】:Dispose of SearchResultCollection after foreach-object在 foreach-object 之后处理 SearchResultCollection
【发布时间】:2017-11-28 19:24:39
【问题描述】:

根据MSDN 备注,.Dispose() 必须在完成后调用System.DirectoryServices.SearchResultCollection

由于实现限制,SearchResultCollection 类在垃圾回收时无法释放其所有非托管资源。 为防止内存泄漏,您必须在不再需要 SearchResultCollection 对象时调用 Dispose 方法

我还读到您应该使用Foreach-Object 而不是foreach 来节省内存,因为foreach 需要将整个SearchResultCollection 保存到内存中,然后才能对其进行迭代。

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

优于

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

如果你使用Foreach-Object,我不知道如何调用.Dispose()

【问题讨论】:

    标签: powershell for-loop active-directory directoryservices


    【解决方案1】:

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

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

    ForEach-Object 在您需要 PowerShell 的流式传输行为并且您可能无法进行有效搜索时很有用。

    【讨论】:

      【解决方案2】:

      比尔·斯图尔特是对的。 .FindAll() 返回一个 IEnumerable,所以你选择哪一个都没关系。

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

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

      【讨论】:

      • foreach($obj in $objResults)相比这样做有什么好处吗?
      • “这样做有什么好处吗?”不,不是。
      • @IMTheNachoMan 正如比尔所说,不,没有。因为您正在处理的对象是一个枚举器,而不是一个预先生成的集合,所以这并不重要;使用最适合您的应用程序的方法。我只是在演示如何运行.Dispose(),如果你选择了这个(正如你提出的问题)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 2015-09-11
      • 2023-03-06
      • 2019-07-16
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多