迭代SearchResultCollection非常慢

时间:2012-06-04 21:40:05

标签: asp.net performance foreach ldap ldap-query

我正在运行一个返回多个条目的LDAP查询,并将它们存储在SearchResultCollection中。我正在迭代搜索SearchResultCollection:

// results is my SearchResultCollection object
foreach (SearchResult sr in results)  
{
    ... do things to each SearchResult in here ...
}

这似乎是最合乎逻辑的方法,但循环令人难以置信慢。当我使用调试器逐步完成循环时,我发现这是初始化foreach循环的第一步,它花费时间 - 实际的迭代是瞬时的。

此外,当我在调试时查看SearchResultCollection的内容时,手表加载变量的内容的时间也一样长。

我有一个理论认为SearchResultCollection实际上并不包含完整的SearchResult对象,而是引用Active Directory服务器中的条目,然后在迭代SearchResultCollection对象时单独获取这些条目。谁能证实这个理论?是否有更好(更快)的方法来获取一组LDAP条目?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,下面帖子中的方法比我自己快得多:

http://msdn.microsoft.com/en-us/library/ms180881(v=vs.80).aspx

...回答你的问题是,似乎你试图通过使用类似的东西在循环中直接处理条目:

     If Not UserAccount.GetDirectoryEntry().Properties("sAMAccountName").Value Is Nothing Then sAMAccountName = UserAccount.Properties("sAMAccountName")(0).ToString()

...这对性能产生了极大的影响,你可以通过在循环中将集合添加到Dictionary然后处理字典来解决这个问题:

    Dim searchResult As SearchResult
    Dim dictLatestLogonDatesTemp As New Dictionary(Of String, Date)
    SearchResults1 = mySearcher.FindAll()
    For Each searchResult In SearchResults1
        Dim propertyKey,sAMAccountName  As String
        Dim dteLastLogonDate As Date = Nothing
        For Each propertyKey In searchResult.Properties.PropertyNames
            Dim valueCollection As ResultPropertyValueCollection = searchResult.Properties(propertyKey)
            For Each propertyValue As Object In valueCollection
                If LCase(propertyKey) = LCase("sAMAccountName") Then sAMAccountName = propertyValue
                If LCase(propertyKey) = LCase("lastLogon") Then dteLastLogonDate = Date.FromFileTime(propertyValue)
            Next propertyValue
        Next propertyKey
        If sAMAccountName <> Nothing Then dictLatestLogonDatesTemp.Add(sAMAccountName, dteLastLogonDate)
    Next searchResult

有点限制因为字典ony有两个条目,但你可以用逗号分隔其他值或使用字典中的值字典:

    Dim tempDictionary As Dictionary(Of String, Dictionary(Of String, String))

希望这有助于某人!

答案 1 :(得分:0)

我想提出的是,将它们添加到数据表中也可以很好地工作,并且比字典具有更多的属性。从迭代2000个用户到搜索结果集合,我花了将近2分钟的时间去不到1-2秒。希望这对其他人有帮助。

  Private Sub getAllUsers()
    Dim r As SearchResultCollection
    Dim de As DirectoryEntry = New DirectoryEntry(GetCurrentDomainPath)
    Dim ds As New DirectorySearcher(de)

    ds.SearchScope = SearchScope.Subtree
    ds.PropertiesToLoad.Add("name")
    ds.PropertiesToLoad.Add("distinguishedName")
    ds.PropertiesToLoad.Add("objectSID")
    ds.Filter = "(&(objectCategory=person)(objectClass=user))" '(!userAccountControl:1.2.840.113556.1.4.803:=2) not disabled users 

    PleaseWait.Status("Loading Users...")
    Application.DoEvents()

    r = ds.FindAll()

    Dim dt As New DataTable
    dt.Columns.Add("Name")
    dt.Columns.Add("SID")

    For Each sr As SearchResult In r
        Dim SID As New SecurityIdentifier(CType(sr.Properties("objectSID")(0), Byte()), 0)
        dt.Rows.Add(sr.Properties("name")(0).ToString(), SID.ToString)
    Next

    With lstResults
        lstResults.DataSource = dt
        .DisplayMember = "name"
        .ValueMember = "SID"
        .Items.Sort()
    End With

End Sub

答案 2 :(得分:-1)

可能有一些方法可以缩短响应时间:

  • 限制搜索范围
  • 使用限制性更强的搜索过滤器
  • 使用更靠近被检索对象的基础对象。

另见