J'ai un programme qui me permet de gérer les utilisateurs sur notre serveur terminal que nous utilisons pour faire la démonstration de notre logiciel. J'ai essayé d'améliorer le performace d'ajouter des utilisateurs au système (il ajoute le compte principal puis il ajoute des sous-comptes si nécessaire, par exemple si j'avais un utilisateur de Demo1 et 3 sous utilisateurs il créerait Demo1, Demo1a, Demo1b, et Demo1c.)Amélioration des performances de System.DirectoryServices.AccountManagement
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();
}
}
}
pas à pas dans le code que j'ai trouvé que user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
est l'appel coûteux, en 5-10 secondes par boucle.
J'ai trouvé que j'avais 5-10 secondes de plus sur chaque appel GroupPrincipal.FindByIdentity()
aussi, donc je l'ai déplacé hors de la boucle, le Save()
n'est pas cher. Avez-vous d'autres recommandations pour accélérer ce processus?
Éditer - Le cas normal serait l'utilisateur existera mais il est probable que le sous-utilisateur n'existe pas, mais il peut exister.