Работа со списками проекта (IZennoList) в ZennoPoster
🔴 ВАЖНЫЕ ОГРАНИЧЕНИЯ И ОСОБЕННОСТИ
⚠️ Списки должны быть созданы заранее
Все списки должны быть созданы в ProjectMaker до выполнения кода
Попытка доступа к несуществующему списку вызовет исключение
⚠️ Связь с внешними файлами
Списки могут быть привязаны к внешним файлам (txt, csv)
Изменения в коде автоматически сохраняются в файл
При работе с файловыми списками lock() обязателен для предотвращения повреждения файла
⚠️ Потокобезопасность
Обычные списки (созданные в ProjectMaker без привязки к файлу) - потокобезопасны, lock() не нужен
Файловые списки (привязанные через Bind к внешнему файлу) - требуют lock() для всех операций
📋 ОСНОВНЫЕ СВОЙСТВА И МЕТОДЫ
Свойства
IZennoList list = project.Lists["MyList"];// Получение количества элементовint count = list.Count;project.SendInfoToLog($"В списке {count} элементов", false);// Проверка на только для чтенияbool isReadOnly = list.IsReadOnly;// Получение элемента по индексуstring item = list[0];string lastItem = list[list.Count - 1];// Установка элемента по индексуlist[0] = "новое значение";
IZennoList targetList = project.Lists["Target"];// Из обычного спискаList<string> tempList = new List<string>();tempList.Add("элемент1");tempList.Add("элемент2");tempList.Add("элемент3");targetList.AddRange(tempList);// Из другого IZennoListIZennoList sourceList = project.Lists["Source"];targetList.AddRange(sourceList);
Получение элементов
Прямой доступ по индексу
IZennoList list = project.Lists["MyList"];// Получение элементаif (list.Count > 0) { string first = list[0]; string last = list[list.Count - 1]; project.SendInfoToLog($"Первый: {first}", false); project.SendInfoToLog($"Последний: {last}", false);}// Безопасное получение с проверкойint index = 5;if (index >= 0 && index < list.Count) { string item = list[index]; project.SendInfoToLog($"Элемент [{index}]: {item}", false);}
GetItem - получение с удалением
IZennoList queue = project.Lists["Queue"];// Получение первого элемента без удаленияstring item = queue.GetItem("0", false);// Получение первого элемента с удалениемstring nextItem = queue.GetItem("0", true);// Получение случайного элемента с удалениемstring randomItem = queue.GetItem("random", true);// Проверка результатаif (!string.IsNullOrEmpty(nextItem)) { project.SendInfoToLog($"Обработка: {nextItem}", false);}
GetItems - получение нескольких элементов
IZennoList batch = project.Lists["Batch"];// Получение диапазона элементов (0, 1, 2)string[] items = batch.GetItems("0-2", false);// Получение первых 5 элементов с удалениемstring[] firstFive = batch.GetItems("0-4", true);// Получение 3 случайных элементовstring[] randomThree = batch.GetItems("3", true);// Обработка результатаforeach (string item in items) { project.SendInfoToLog($"Элемент: {item}", false);}
Удаление элементов
RemoveAt - удаление по индексу
IZennoList processing = project.Lists["Processing"];// Удаление первого элементаif (processing.Count > 0) { processing.RemoveAt(0);}// Удаление последнего элементаif (processing.Count > 0) { processing.RemoveAt(processing.Count - 1);}// Удаление нескольких элементов с концаint toRemove = 5;for (int i = 0; i < toRemove && processing.Count > 0; i++) { processing.RemoveAt(processing.Count - 1);}
IZennoList items = project.Lists["Items"];string searchItem = "target_value";int index = items.IndexOf(searchItem);if (index >= 0) { project.SendInfoToLog($"Найден на позиции: {index}", false);} else { project.SendInfoToLog("Элемент не найден", false);}
Insert - вставка по индексу
IZennoList list = project.Lists["MyList"];// Вставка в началоlist.Insert(0, "новый_первый");// Вставка в серединуif (list.Count >= 5) { list.Insert(5, "вставка_в_середину");}
CopyTo - копирование в массив
IZennoList source = project.Lists["Source"];// Создание массива нужного размераstring[] array = new string[source.Count];// Копирование всех элементовsource.CopyTo(array, 0);// Использование скопированных данныхforeach (string item in array) { project.SendInfoToLog(item, false);}
Bind - привязка к файлу
IZennoList list = project.Lists["FileList"];// Привязка к файлуstring filePath = Path.Combine(project.Directory, "data.txt");list.Bind(filePath);// После привязки все операции требуют lock()lock (list) { list.Add("новая_строка");}project.SendInfoToLog($"Список привязан к {filePath}", false);
🔒 ПОТОКОБЕЗОПАСНАЯ РАБОТА
Когда нужен lock()
Файловые списки - ВСЕГДА используйте lock()
IZennoList fileList = project.Lists["FileList"];string filePath = Path.Combine(project.Directory, "data.txt");fileList.Bind(filePath);// Все операции с файловым спискомlock (fileList) { fileList.Add("данные"); string item = fileList[0]; fileList.RemoveAt(0);}
Обычные списки - lock() НЕ нужен
IZennoList normalList = project.Lists["NormalList"];// Операции без lock() - потокобезопасноnormalList.Add("элемент");string item = normalList[0];normalList.RemoveAt(0);
Правильная синхронизация
IZennoList fileList = project.Lists["FileList"];// Подготовка данных ВНЕ блокировкиstring processedData = ProcessData();// Быстрая операция В блокировкеlock (fileList) { fileList.Add(processedData);}// Неправильно - долгая операция в locklock (fileList) { Thread.Sleep(5000); // ❌ Блокирует другие потоки fileList.Add("data");}