IZennoList profiles = project.Lists["profiles"]; // Допустим у нас есть список профилей/аккаунтов с которого ведётся рассылка
IZennoList ids = project.Lists["ids"]; // Допустим, у нас есть список ID по которым необходимо провести рассылку
IZennoList queue = project.Lists["queue"]; // Список для хранения данных в виде id|profile
if(profiles.Count == 0) { // Если данных нет - добавляю демо данные
lock(SyncObjects.ListSyncer) { // обеспечиваю добавление данных в многопотоке
profiles.Add("profile_1"); // заполняю демо данными
profiles.Add("profile_2");
profiles.Add("profile_3");
}
}
if(ids.Count == 0) { // Если данных нет - добавляю демо данные
lock(SyncObjects.ListSyncer) { // обеспечиваю добавление данных в многопотоке
ids.Add("00001"); // заполняю демо данными
ids.Add("00010");
ids.Add("00100");
ids.Add("01000");
ids.Add("10000");
}
}
// Получаю строчку с ИД, с которого необходимо выполнить какую-то работу
string id = string.Empty;
lock(SyncObjects.ListSyncer){
if(ids.Count > 0) {
id = ids.GetItem("0", true); // Получаем первую строчку с удалением, чтобы одновременно несколько потоков не могли работать с одним ид
}
}
if(string.IsNullOrEmpty(id)) {
// профиль не возвращаем - ещё не брали
// ид не возвращаем - он пустой
throw new Exception("Пустой ID");
}
string profile = string.Empty;
if(queue.Count >0 ) {
string[] temp_queue = queue.Where(x=> x.Split('|')[0] == id).Select(x=>x.Split('|')[1]).ToArray(); // получаем профиль, с которого уже производилась рассылка на этот ид
profile = temp_queue.Length > 0 ? temp_queue[0] : string.Empty;
}
if(string.IsNullOrEmpty(profile)){ // На этот ИД ещё не производилась рассылка - берем новый профиль
lock(SyncObjects.ListSyncer){
if(profiles.Count > 0) {
profile = profiles.GetItem("0", true); // Получаем первую строчку с удалением, чтобы одновременно несколько потоков не могли работать с одним профилем
}
}
}
else {
// на этот ИД уже производилась рассылка с профиля - используем этот профиль, он уже в переменной
// Необходимо удалить его из списка, чтобы другой поток не начал работу с ним
lock(SyncObjects.ListSyncer){
string[] temp_profiles = profiles.Where(x=> x!= profile).ToArray();
profiles.Clear();
if(temp_profiles.Length > 0) profiles.AddRange(temp_profiles);
}
}
if(string.IsNullOrEmpty(profile)){
if(!string.IsNullOrEmpty(id)) ids.Add(id); // Возвращаем ИД обратно
// профиль не возвращаем - он пустой
throw new Exception("Вернули ИД обратно - нет профиля для работы");
}
// В результате, в нас есть подготовлен ИД и профиль, с которых будем производить рассылку
// Где-то здесь производим рассылку
project.SendInfoToLog(string.Format("Сделали рассылку на ID: {0} профиль: {1}", id, profile),true);
// Добавили в список связку ИД, профиль, чтобы при следующем обращении использовать этот же профиль
lock(SyncObjects.ListSyncer){
queue.Add(string.Join("|", new[]{id, profile}));
}
// Вернули назад профиль
lock(SyncObjects.ListSyncer){
profiles.Add(profile);
}
// Вернули назад ид
lock(SyncObjects.ListSyncer){
ids.Add(id);
}
// Также по количеству добавлений можем узнать сколько раз была произведена отправка на определенный ИД
project.SendInfoToLog(string.Format(@"На id: {0} производилась рассылка: {1} раз", id, queue.Where(x=> x.Split('|')[0] == id).Count()), true);
// Нужно быть аккуратным, так как файл списка будет расти
// Если с какими-то ид больше работать не предполагается, необходимо удалять их из списка, либо работать точно также с базой данных