///<summary>Generic function that launches different thread methods depending on how isSyncUsers and isSyncLocks are set. Set only one or the other to true.</summary> private static string PushSecurity(List <CentralConnection> listConns, bool isUsers, bool isLocks) { //Get CEMT users, groups, and associated permissions ListSyncErrors = new List <string>(); _listCEMTUsers = Userods.GetUsersForCEMT(); _securityLockDate = PrefC.GetDate(PrefName.SecurityLockDate).ToShortDateString(); _securityLockDays = PrefC.GetInt(PrefName.SecurityLockDays); _securityLockAdmin = PrefC.GetBool(PrefName.SecurityLockIncludesAdmin); _securityCentralLock = PrefC.GetBool(PrefName.CentralManagerSecurityLock); _syncCode = PrefC.GetString(PrefName.CentralManagerSyncCode); _listAlertSubs = AlertSubs.GetAll(); List <CentralUserData> listCentralUserData = new List <CentralUserData>(); List <UserGroup> listUserGroups = UserGroups.GetCEMTGroups(); foreach (UserGroup userGroup in listUserGroups) //for each CEMT user group //get all usergroupattaches, userods, and grouppermissions. { List <UserGroupAttach> listUserGroupAttaches = UserGroupAttaches.GetForUserGroup(userGroup.UserGroupNum); List <Userod> listUserOds = Userods.GetForGroup(userGroup.UserGroupNum); List <GroupPermission> listGroupPermissions = GroupPermissions.GetPerms(userGroup.UserGroupNum); //then create a new CentralUserData and add it to the list. listCentralUserData.Add(new CentralUserData(userGroup, listUserOds, listGroupPermissions, listUserGroupAttaches)); } string failedConns = ""; string nameConflicts = ""; string failedSyncCodes = ""; for (int i = 0; i < listConns.Count; i++) { List <CentralUserData> listCentralDataForThreads = new List <CentralUserData>(); for (int j = 0; j < listCentralUserData.Count; j++) { listCentralDataForThreads.Add(listCentralUserData[j].Copy()); } ODThread odThread = null; if (isUsers) { odThread = new ODThread(ConnectAndSyncUsers, new object[] { listConns[i], listCentralDataForThreads }); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper)); } else if (isLocks) { odThread = new ODThread(ConnectAndSyncLocks, new object[] { listConns[i] }); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper)); } else { odThread = new ODThread(ConnectAndSyncAll, new object[] { listConns[i], listCentralDataForThreads }); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper)); } odThread.GroupName = "Sync"; odThread.Start(false); } ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Sync"); List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Sync"); for (int i = 0; i < listComplThreads.Count; i++) { if (listComplThreads[i].Tag == null) { continue; //Failed due to lacking credentials } failedConns += ((List <string>)listComplThreads[i].Tag)[0]; nameConflicts += ((List <string>)listComplThreads[i].Tag)[1]; failedSyncCodes += ((List <string>)listComplThreads[i].Tag)[2]; listComplThreads[i].QuitAsync(); } string errorText = ""; if (failedConns == "" && nameConflicts == "" && failedSyncCodes == "") { errorText += "Done"; } if (failedConns != "") { errorText = "Failed Connections:\r\n" + failedConns + "Please try these connections again.\r\n"; } if (nameConflicts != "") { errorText += "Name Conflicts:\r\n" + nameConflicts + "Please rename users and try again.\r\n"; } if (failedSyncCodes != "") { errorText += "Incorrect Sync Codes:\r\n" + failedSyncCodes + "\r\n"; } return(errorText); }