我有大约 50,000 个 ID 需要在 AD 中查找,因此我使用 TPL 设置了 10 个线程来同时处理列表。浏览这些 ID 并获取所需信息需要 5 个多小时,如下所示。知道为什么吗?这是正常的还是我的代码放慢了速度?
我测试过,一个 ID 可能需要 3-4 秒到有时 70 或 80 秒来完成任何给定 ID 的迭代。
谢谢
maxThreads = 10;
int hdCount = UserProfileDictionary.Count;
int completedCount = 0;
foreach (var intKey in UserProfileDictionary.Keys.ToList())
{
String ID = intKey;
MyTasks.Add(System.Threading.Tasks.Task.Factory.StartNew(() => GetADInfo(ID, ref UserProfileDictionary, supportedOUCNs), TaskCreationOptions.LongRunning));
completedCount++;
Console.Write("\rCompleted " + completedCount + " out of " + hdCount);
lock (numActiveThreadLock)
numActiveThreads++;
bool continuethreads = false;
while (continuethreads == false)
{
if (numActiveThreads < maxThreads)
continuethreads = true;
else
System.Threading.Thread.Sleep(1000);
}
}
Task.WaitAll(MyTasks.ToArray(), -1);
MyTasks.Clear();
protected static void GetADInfo(String ID, ref Dictionary<string, UserProfile> UserProfileDictionary, List<string> supportedOUCNs)
{
using (DirectoryEntry entry = new DirectoryEntry("LDAP://DC=A,DC=B,DC=C"))
{
using (DirectorySearcher mySearcher = new DirectorySearcher(entry))
{
mySearcher.SearchScope = SearchScope.Subtree;
mySearcher.CacheResults = false;
mySearcher.PropertiesToLoad.AddRange(new string[] { "cn", "displayName", "canonicalName", "userAccountControl", "distinguishedName"});
mySearcher.Filter = ("(&(samAccountType=805306368)(sAMAccountName=" + ID + "))");
foreach (SearchResult result in mySearcher.FindAll())
{
String displayname = "";
String acctstatus = "N/A";
String acctLocation = "N/A";
String strUserDN = result.Properties["distinguishedName"][0].ToString();
try
{
displayname = result.Properties["displayName"][0].ToString();
}
catch
{
displayname = "N/A";
}
acctLocation = result.Properties["canonicalName"][0].ToString().Replace(@"/" + result.Properties["cn"][0].ToString(), "");
int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
bool disabled = ((userAccountControl & 2) > 0);
if (disabled == true)
acctstatus = "Disabled";
else
acctstatus = "Enabled";
String suptUser = "NOT SUPPORTED";
foreach (String CN in supportedOUCNs)
{
if (acctLocation.ToLower().Contains(CN.ToLower()) == true)
{
suptUser = "SUPPORTED";
break;
}
}
Dictionary<string, string> usermemberOfDictionary = new Dictionary<string, string>();
List<ResourceInfo> resInfoList = new List<ResourceInfo>();
entry.Path = "LDAP://" + strUserDN;
entry.RefreshCache(new string[] { "msds-memberOfTransitive" });
foreach (String strDN in entry.Properties["msds-memberOfTransitive"])
{
usermemberOfDictionary.Add(strDN, "GROUP");
}
String userOU = strUserDN;
String[] OUArray = userOU.Split(',');
foreach (String OU in OUArray)
{
userOU = userOU.Replace(OU + ",", "");
if (userOU != "DC=net")
{
usermemberOfDictionary.Add(userOU, "OU");
}
}
foreach (KeyValuePair<string, string> DNEntry in usermemberOfDictionary)
{
String strObject = "";
entry.Path = "LDAP://" + DNEntry.Key;
entry.RefreshCache(new string[] { "cn", "DriveMapping", "Priority" });
if (DNEntry.Value == "GROUP")
strObject = entry.Properties["cn"][0].ToString();
else
strObject = DNEntry.Key;
try
{
if (entry.Properties["DriveMapping"].Count > 0)
{
String resPriority = "";
try
{
resPriority = entry.Properties["Priority"][0].ToString();
}
catch
{
resPriority = "N/A";
}
PropertyValueCollection driveResources = entry.Properties["DriveMapping"];
for (int DRindex = 0; DRindex < driveResources.Count; DRindex++)
{
if (driveResources[DRindex].ToString().ToLower().Contains("<username>") == true)
{
String[] driveResourceArray = driveResources[DRindex].ToString().Split(',');
String resLetter = driveResourceArray[0] + @":\";
String resServer = driveResourceArray[1];
String resShare = driveResourceArray[2];
resInfoList.Add(new ResourceInfo
{
resObject = strObject,
resLetter = resLetter,
resServer = resServer,
resShare = resShare,
resPriority = resPriority,
resTargetLink = @"\\" + resServer + @"\" + resShare.ToLower().Replace("<username>", ID.ToLower()),
resServerSupportStatus = "NOT SUPPORTED",
resServerStatus = "OFFLINE",
resShareStatus = "NOT ACTIVE"
});
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
lock(UserProfileDictionaryLock)
{
UserProfile userProfile = UserProfileDictionary[ID.ToLower()];
userProfile.displayname = displayname;
userProfile.acctstatus = acctstatus;
userProfile.acctLocation = acctLocation;
userProfile.resources = resInfoList;
userProfile.userSupportStatus = suptUser;
UserProfileDictionary[ID.ToLower()] = userProfile;
}
}
mySearcher.FindAll().Dispose();
}
}
lock (numActiveThreadLock)
{
numActiveThreads--;
}
}