以下代码允许我从DirectoryServices中提取整个全局地址列表。代码是功能性的,因为它给了我我需要的东西。问题是返回1000个对象大约需要20秒。我有什么办法可以加快速度吗?
public static List<Address> GetGlobalAddressList()
{
using (var searcher = new DirectorySearcher())
{
using (var entry = new DirectoryEntry(searcher.SearchRoot.Path, "*****", "*****"))
{
searcher.Filter = "(&(mailnickname=*)(objectClass=user))";
searcher.PropertiesToLoad.Add("cn");
searcher.PropertyNamesOnly = true;
searcher.SearchScope = SearchScope.Subtree;
searcher.Sort.Direction = SortDirection.Ascending;
searcher.Sort.PropertyName = "cn";
var results = searcher.FindAll();
var addressList = new List<Address>();
foreach (SearchResult i in results)
{
var address = new Address
{
DisplayName = (string)i.GetDirectoryEntry().Properties["displayName"].Value,
Mail = (string) i.GetDirectoryEntry().Properties["mail"].Value
};
addressList.Add(address);
}
return addressList;
}
}
}
public class Address
{
public string DisplayName { get; set; }
public string Mail { get; set; }
}
答案 0 :(得分:0)
从您的代码中我可以看到您正在返回一个完全填充的列表。您可以在识别后立即修改此方法以获得返回值。要执行此操作,请将返回类型从List更改为Ienumerable,然后删除返回列表以及您添加到该列表的位置返回带有yeild return的新创建的对象
dotnetperls对于yeild语句有一个很好的定义。
你会有类似的东西......
public static IEnumerable<Address> GetGlobalAddressList()
{
using (var searcher = new DirectorySearcher())
{
using (var entry = new DirectoryEntry(searcher.SearchRoot.Path, "*****", "*****"))
{
searcher.Filter = "(&(mailnickname=*)(objectClass=user))";
searcher.PropertiesToLoad.Add("cn");
searcher.PropertyNamesOnly = true;
searcher.SearchScope = SearchScope.Subtree;
searcher.Sort.Direction = SortDirection.Ascending;
searcher.Sort.PropertyName = "cn";
foreach (SearchResult i in searcher.FindAll())
{
var address = new Address
{
DisplayName = (string)i.GetDirectoryEntry().Properties["displayName"].Value,
Mail = (string) i.GetDirectoryEntry().Properties["mail"].Value
};
yeild return address;
}
}
}
}
您还应该查看Joes已接受的答案。
答案 1 :(得分:0)
事实证明GetDirectoryEntry()是问题所在。显然使用它是非常耗费资源的,因为它允许您在检索后实际更新Directory条目。换句话说,每次调用它都会在每次调用时对Active Directory进行额外调用。我只需要访问/读取属性而不更新它们,所以我重写了没有GetDirectoryEntry()的方法。它现在立即返回整个全局地址列表。解决我问题的代码如下。
[WebMethod()]
public static List<Address> GetAddresses()
{
using (var objsearch = new DirectorySearcher())
{
objsearch.Filter = "(& (mailnickname=*)(objectClass=user))";
objsearch.SearchScope = SearchScope.Subtree;
objsearch.PropertiesToLoad.Add("cn");
objsearch.PropertiesToLoad.Add("mail");
objsearch.PropertyNamesOnly = false;
objsearch.Sort.Direction = SortDirection.Ascending;
objsearch.Sort.PropertyName = "cn";
objsearch.PageSize = 5000;
var colresults = objsearch.FindAll();
var addressList = new List<Address>();
foreach (SearchResult objresult in colresults)
{
var address = new Address();
var cn = objresult.Properties["cn"];
if (cn.Count >= 1) address.DisplayName = (cn[0]) as string;
var mail = objresult.Properties["mail"];
if (mail.Count >= 1) address.Mail = (mail[0]) as string;
addressList.Add(address);
}
return addressList;
}
}