Помогите с логикой и (Lock'ом) для взятия списка в много потоке

backoff

Client
Регистрация
20.04.2015
Сообщения
5 931
Благодарностей
6 389
Баллы
113
Приветствую.
Столкнулся со следующей ситуацией. Обрисую действия.

Берем строку из списка, если есть - все ок, если нет, то дальше идут действия (надо взять все файлы из папки и подпапок)

1. Берем все файлы и получаем текстовый файл вида
C:/zenka/proekti/papka1/papka2/papka3/papka4/papka5/papka6/Files/25-8-2020/43j534kjb53k45nk34.file
C:/zenka/proekti/papka1/papka2/papka3/papka4/papka5/papka6/Files/25-8-2020/qekertiu3847y528435342.file

то есть после взятия всех файлов мы имеем огромные текстовик, на 500мб - это конечно же затрудняет сильно работу, по работе с файлом.
что предпринял (MySQL использовать не хочу - не советуйте)

Обрезаем все строки до такого вида: 25-8-2020/qekertiu3847y528435342.file ... и файл начинает весить 30мб, что значительно ускоряет работу
В дальнейшем данная строка пути ( C:/zenka/proekti/papka1/papka2/papka3/papka4/papka5/papka6/Files/ ) просто подставляется из переменной

Но вся проблема заключается в том, что при много потоке, когда заканчиваются строки, каждый из потоков делает сбор данных файлов, и конечно же получается белиберда.

Вопрос:

Как сделать так, чтоб на кубиках была обработка данного участка в один поток, чтоб просто корректно отрабатывал взятие и последующую манипуляцию. Можно конечно перед действиями поставить задержку по времени в секах типа от 50-150, и первый поток все сделает, но если более одного потока закончат ожидание в одно и тоже время... не вариант получается.

спасибо
 
Последнее редактирование:

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 694
Баллы
113
я для своих нужд такую ситуацию обрабатываю так :
многопоток разбирает строки, если они заканчиваются , то добавляют попытку отдельному шаблону, который только и делает что заполняет файл названиями файлов и работает он только в один поток. Ну и с проверкой количества попыток , что бы не молотил лишний раз. и в самом шабе заполнителе тоже в начале есть проверка на пустой файл. после заполнения пауза 5 секунд на всякий. А многопоток после запуска шаба уходит на ожидание появления информации в файле с таймаутом 60 секунд. как только инфа появляется многопоток начинает опять хавать строки.

ну можно и все в одном шабе сделать мне кажется. например так:
как только обнаружилась ситуация с пустым файлом , в темповый список добавить метку из рандомного текста, при условии что в темповом списке пусто и подождать 5 секунд. потом сравнить первую строку со своей меткой и если совпадают то заполнять список, если не равны то переходить на ожидание заполнения файла другим потоком. после заполнения выждать 10 секунд и очистить темповую список. очиску темпового списка желательно сделать и в конце работы шаба, с проверкой даты последнего изменения (ну например 2-3 минуты можно считать данные неактуальные), что бы не завешивалась работа при непредвиденных вылетах/сбоях техники.
 
Последнее редактирование:

backoff

Client
Регистрация
20.04.2015
Сообщения
5 931
Благодарностей
6 389
Баллы
113
тоже об этом подумал, но хотелось бы более элегантнее )
 

Moadip

Client
Регистрация
26.09.2015
Сообщения
509
Благодарностей
823
Баллы
93
Как сделать так, чтоб на кубиках была обработка данного участка в один поток, чтоб просто корректно отрабатывал взятие и последующую манипуляцию. Можно конечно перед действиями поставить задержку по времени в секах типа от 50-150, и первый поток все сделает, но если более одного потока закончат ожидание в одно и тоже время... не вариант получается.
Сделать через блокировку.
Проверятся список, если есть там что - берется строка с удалением. Если нет, то заполняется инфой какие есть файлы в каталоге, а потом уже берется строка.
Пример взятия файлов простой, чтобы не усложнять. Дальше там уже можно наворотить по желанию. Сделать тот же рекурсивный перебор всех подкаталогов.
C#:
var files = project.Lists["files"];
var filesDir = project.Directory + "\\Files\\"; // путь к папке с файлами

lock(CommonCode.SyncObject)
{
    if(!files.Any()) // если список пуст, собираем файлы в папке
    {
        var list = Directory.GetFiles(filesDir)
            .Select(f => Path.GetFileName(f)) // берем только имя файла + расширение
            .ToList();
        
        files.AddRange(list);
    }
    
    project.Variables["fileName"].Value = files[0];
    files.RemoveAt(0);
}
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)