У меня есть программа, которая позволит мне управлять пользователями на нашем терминальном сервере, который мы используем для демонстрации нашего программного обеспечения. Я пытался улучшить производительность добавления пользователей в систему (он добавляет основную учетную запись, затем добавляет дополнительные учетные записи, если это необходимо, например, если бы у меня был пользователь Demo1 и 3 вспомогательных пользователя, он создал бы Demo1, Demo1a, Demo1b, и Demo1c.)
private void AddUsers(UserInfo userInfo, InfinityInfo infinityInfo, int subUserStart)
{
using (GroupPrincipal r = GroupPrincipal.FindByIdentity(context, "Remote Desktop Users"))
using (GroupPrincipal u = GroupPrincipal.FindByIdentity(context, "Users"))
for(int i = subUserStart; i < userInfo.SubUsers; ++i)
{
string username = userInfo.Username;
if (i >= 0)
{
username += (char)('a' + i);
}
UserPrincipal user = null;
try
{
if (userInfo.NewPassword == null)
throw new ArgumentNullException("userInfo.NewPassword", "userInfo.NewPassword was null");
if (userInfo.NewPassword == "")
throw new ArgumentOutOfRangeException("userInfo.NewPassword", "userInfo.NewPassword was empty");
user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
if (user == null)
{
user = new UserPrincipal(context, username, userInfo.NewPassword, true);
user.UserCannotChangePassword = true;
user.PasswordNeverExpires = true;
user.Save();
r.Members.Add(user);
u.Members.Add(user);
}
else
{
user.Enabled = true;
user.SetPassword(userInfo.NewPassword);
}
IADsTSUserEx iad = (IADsTSUserEx)((DirectoryEntry)user.GetUnderlyingObject()).NativeObject;
iad.TerminalServicesInitialProgram = GenerateProgramString(infinityInfo);
iad.TerminalServicesWorkDirectory = Service.Properties.Settings.Default.StartInPath;
iad.ConnectClientDrivesAtLogon = 0;
user.Save();
r.Save();
u.Save();
OperationContext.Current.GetCallbackChannel<IRemoteUserManagerCallback>().FinishedChangingUser(username);
}
catch (Exception e)
{
string errorString = String.Format("Could not Add User:{0} Sub user:{1}", userInfo.Username, i);
try
{
if (user != null)
errorString += "\nSam Name: " + user.SamAccountName;
}
catch { }
OperationContext.Current.GetCallbackChannel<IRemoteUserManagerCallback>().UserException(errorString, e);
}
finally
{
if (user != null)
user.Dispose();
}
}
}
Проходя по коду, я обнаружил, что user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
- это дорогой вызов, занимающий 5-10 секунд на цикл.
Я обнаружил, что при каждом вызове GroupPrincipal.FindByIdentity()
у меня было еще 5-10 секундное попадание, поэтому я переместил его из цикла, Save()
не дорогой. У вас есть другие рекомендации, которые помогут ускорить это?
Редактировать -
Обычный случай: пользователь будет существовать, но, вероятно, субпользователь не существует, но он может существовать.