当 AD/NT 用户不存在时,DirectoryEntry.Exist 在 C# 中花费超过 10 秒的时间
DirectoryEntry.Exist in C# taking more than 10 Sec time when AD/NT user is not present
问题也可以通过以下简单应用程序触发:
Stopwatch watch = new Stopwatch();
string[] userNames = {"JunkName", "DummyName"};
foreach (var name in userNames)
{
watch.Reset();
watch.Start();
if (DirectoryEntry.Exists("WinNT://" + Environment.MachineName + "/" + name))
{
Console.WriteLine($"user {name} found in " + watch.ElapsedMilliseconds + "ms");
}
else
{
Console.WriteLine($"user {name} not found in " + watch.ElapsedMilliseconds + "ms");
}
}
没有正确的根本原因可以判断是 Microsoft API 问题还是其他问题。
然而,大多数搜索结果都提到如果您搜索一个不存在的用户,而不是 return false,DirectoryEntry.Exists
方法将抛出异常。
但在我们的示例应用程序中它没有抛出任何异常。
我还尝试了以下一些建议来检查这些示例代码需要多少执行时间,发现这些代码第一次也需要超过 11 秒。
示例 1:
using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
{
UserPrincipal up = UserPrincipal.FindByIdentity(pc,
IdentityType.SamAccountName, name);
UserExists = (up != null);
}
示例 2:
DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
bool UserExists =
dirEntryLocalMachine.Children.Find(userIdentity, "user") != null;
只是高度怀疑 OS 更新会导致问题,可能是我的假设是错误的。
提前致谢
有一天我遇到了同样的延迟,所以我写了这个更快的函数,也许它可以帮助你:
private string FindUserSID(string domain, string user)
{
string output;
try
{
NTAccount account = new NTAccount(domain + @"\" + user);
SecurityIdentifier s = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
output = s.ToString();
}
catch (IdentityNotMappedException)
{
output = null;
}
return output;
}
问题也可以通过以下简单应用程序触发:
Stopwatch watch = new Stopwatch();
string[] userNames = {"JunkName", "DummyName"};
foreach (var name in userNames)
{
watch.Reset();
watch.Start();
if (DirectoryEntry.Exists("WinNT://" + Environment.MachineName + "/" + name))
{
Console.WriteLine($"user {name} found in " + watch.ElapsedMilliseconds + "ms");
}
else
{
Console.WriteLine($"user {name} not found in " + watch.ElapsedMilliseconds + "ms");
}
}
没有正确的根本原因可以判断是 Microsoft API 问题还是其他问题。
然而,大多数搜索结果都提到如果您搜索一个不存在的用户,而不是 return false,DirectoryEntry.Exists
方法将抛出异常。
但在我们的示例应用程序中它没有抛出任何异常。
我还尝试了以下一些建议来检查这些示例代码需要多少执行时间,发现这些代码第一次也需要超过 11 秒。
示例 1:
using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
{
UserPrincipal up = UserPrincipal.FindByIdentity(pc,
IdentityType.SamAccountName, name);
UserExists = (up != null);
}
示例 2:
DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
bool UserExists =
dirEntryLocalMachine.Children.Find(userIdentity, "user") != null;
只是高度怀疑 OS 更新会导致问题,可能是我的假设是错误的。
提前致谢
有一天我遇到了同样的延迟,所以我写了这个更快的函数,也许它可以帮助你:
private string FindUserSID(string domain, string user)
{
string output;
try
{
NTAccount account = new NTAccount(domain + @"\" + user);
SecurityIdentifier s = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
output = s.ToString();
}
catch (IdentityNotMappedException)
{
output = null;
}
return output;
}