为什么我的目录搜索需要这么长时间?
Why is my directory search taking so long?
我一直在对 REST 中的性能进行故障排除 API 我已经构建了 returns 基于提供的搜索词的 Active Directory 用户列表。根据我为测试目的而内置的一些日志记录,我可以看到获取设置(例如 LDAP 搜索信息)和检索所有搜索结果的整个过程不到一秒钟:
30/08/2017 3:37:58 PM | Getting search results.
30/08/2017 3:37:58 PM | Retrieving default settings
30/08/2017 3:37:58 PM | Default settings retrieved. Creating directoryEntry
30/08/2017 3:37:58 PM | Search retrieved.
30/08/2017 3:37:58 PM | Iterating through search results.
30/08/2017 3:38:16 PM | Search results iteration complete.
但是,如您所见,遍历这些搜索结果并填充我的用户列表需要 18 秒。这是我的代码:
SearchResultCollection resultList = new DirectorySearcher(CreateDirectoryEntry())
{
Filter = ("(&(objectClass=user) (cn=*" + SearchTerm + "*))"),
PropertiesToLoad =
{
"givenName",
"sn",
"sAMAccountName",
"mail"
}
}.FindAll();
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
try
{
thisUser.Firstname = result.Properties["givenName"][0].ToString();
}
catch
{
thisUser.Firstname = "Firstname not found";
}
try
{
thisUser.Lastname = result.Properties["sn"][0].ToString();
}
catch
{
thisUser.Lastname = "Lastname not found";
}
try
{
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
}
catch
{
thisUser.EmailAddress = "Email address not found";
}
UserList.Add(thisUser);
}
它很普通,没有做任何花哨的事情。知道为什么这会这么慢,或者关于我可以做些什么来加快速度有什么建议吗?
更新
根据评论和回答,我从代码中删除了空检查。所以现在看起来像这样:
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
thisUser.Firstname = result.Properties["givenName"][0].ToString();
thisUser.Lastname = result.Properties["sn"][0].ToString();
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
UserList.Add(thisUser);
}
这并没有提高性能。我可以看到这个循环仍然需要大约 18 秒,即使只返回一个结果也是如此。 (这也证明了我的广告中糟糕的数据意味着我需要这个空检查!)
你可以尝试类似的方法:
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
if(result.Properties["givenName"][0] != null)
thisUser.Firstname = result.Properties["givenName"][0].ToString();
else
thisUser.Firstname = "Firstname not found";
if(thisUser.Lastname = result.Properties["sn"][0] != null)
thisUser.Lastname = result.Properties["sn"][0].ToString();
else
thisUser.Lastname = "Lastname not found";
if(result.Properties["mail"][0] != null)
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
else
thisUser.EmailAddress = "Email address not found";
UserList.Add(thisUser);
}
您在设置 thisUser
的属性时依赖于例外情况,这取决于您的目录,对于用户来说,可能并非如此 exceptional他们的 givenName
、sn
、and/or mail
属性已填充。如果您的搜索结果列表很长,所有这些例外情况都会累加起来。考虑检查是否存在所需的 属性 而不是使用 try
/catch
块:
thisUser.Firstname = result.Properties.Contains("givenName")
? result.Properties["givenName"][0].ToString()
: "Firstname not found";
thisUser.Lastname = result.Properties.Contains("sn")
? result.Properties["sn"][0].ToString()
: "Lastname not found";
thisUser.EmailAddress = result.Properties.Contains("mail")
? result.Properties["mail"][0].ToString()
: "Email address not found";
您可以使用 null-conditional operators from C# 6 with the null-coalescing operator 将其简化为以下内容:
thisUser.Firstname = result.Properties["givenName"]?[0]?.ToString() ?? "Firstname not found";
thisUser.Lastname = result.Properties["sn"]?[0]?.ToString() ?? "Lastname not found";
thisUser.EmailAddress = result.Properties["mail"]?[0]?.ToString() ?? "Email address not found";
我一直在对 REST 中的性能进行故障排除 API 我已经构建了 returns 基于提供的搜索词的 Active Directory 用户列表。根据我为测试目的而内置的一些日志记录,我可以看到获取设置(例如 LDAP 搜索信息)和检索所有搜索结果的整个过程不到一秒钟:
30/08/2017 3:37:58 PM | Getting search results.
30/08/2017 3:37:58 PM | Retrieving default settings
30/08/2017 3:37:58 PM | Default settings retrieved. Creating directoryEntry
30/08/2017 3:37:58 PM | Search retrieved.
30/08/2017 3:37:58 PM | Iterating through search results.
30/08/2017 3:38:16 PM | Search results iteration complete.
但是,如您所见,遍历这些搜索结果并填充我的用户列表需要 18 秒。这是我的代码:
SearchResultCollection resultList = new DirectorySearcher(CreateDirectoryEntry())
{
Filter = ("(&(objectClass=user) (cn=*" + SearchTerm + "*))"),
PropertiesToLoad =
{
"givenName",
"sn",
"sAMAccountName",
"mail"
}
}.FindAll();
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
try
{
thisUser.Firstname = result.Properties["givenName"][0].ToString();
}
catch
{
thisUser.Firstname = "Firstname not found";
}
try
{
thisUser.Lastname = result.Properties["sn"][0].ToString();
}
catch
{
thisUser.Lastname = "Lastname not found";
}
try
{
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
}
catch
{
thisUser.EmailAddress = "Email address not found";
}
UserList.Add(thisUser);
}
它很普通,没有做任何花哨的事情。知道为什么这会这么慢,或者关于我可以做些什么来加快速度有什么建议吗?
更新
根据评论和回答,我从代码中删除了空检查。所以现在看起来像这样:
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
thisUser.Firstname = result.Properties["givenName"][0].ToString();
thisUser.Lastname = result.Properties["sn"][0].ToString();
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
UserList.Add(thisUser);
}
这并没有提高性能。我可以看到这个循环仍然需要大约 18 秒,即使只返回一个结果也是如此。 (这也证明了我的广告中糟糕的数据意味着我需要这个空检查!)
你可以尝试类似的方法:
foreach (SearchResult result in resultList)
{
ADUser thisUser = new ADUser();
if(result.Properties["givenName"][0] != null)
thisUser.Firstname = result.Properties["givenName"][0].ToString();
else
thisUser.Firstname = "Firstname not found";
if(thisUser.Lastname = result.Properties["sn"][0] != null)
thisUser.Lastname = result.Properties["sn"][0].ToString();
else
thisUser.Lastname = "Lastname not found";
if(result.Properties["mail"][0] != null)
thisUser.EmailAddress = result.Properties["mail"][0].ToString();
else
thisUser.EmailAddress = "Email address not found";
UserList.Add(thisUser);
}
您在设置 thisUser
的属性时依赖于例外情况,这取决于您的目录,对于用户来说,可能并非如此 exceptional他们的 givenName
、sn
、and/or mail
属性已填充。如果您的搜索结果列表很长,所有这些例外情况都会累加起来。考虑检查是否存在所需的 属性 而不是使用 try
/catch
块:
thisUser.Firstname = result.Properties.Contains("givenName")
? result.Properties["givenName"][0].ToString()
: "Firstname not found";
thisUser.Lastname = result.Properties.Contains("sn")
? result.Properties["sn"][0].ToString()
: "Lastname not found";
thisUser.EmailAddress = result.Properties.Contains("mail")
? result.Properties["mail"][0].ToString()
: "Email address not found";
您可以使用 null-conditional operators from C# 6 with the null-coalescing operator 将其简化为以下内容:
thisUser.Firstname = result.Properties["givenName"]?[0]?.ToString() ?? "Firstname not found";
thisUser.Lastname = result.Properties["sn"]?[0]?.ToString() ?? "Lastname not found";
thisUser.EmailAddress = result.Properties["mail"]?[0]?.ToString() ?? "Email address not found";