Подскажите Многопоток С# с удалением и загрузкой картинок

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
774
Благодарностей
517
Баллы
93
Добрый день, возникла проблема при работе с картинками в многопотоке С#.
Шаблон берет картинку из папки, загружает ее на сервер, сохраняет под новым именем, старую картинку удаляет. Во время работы многопотока, бывает ситуация, когда 2ой шаблон начинает работать с картинкой и во время работы 1ый шаблон удаляет эту картинку и крашится 2ой шаблон.

Подскажите, как лучше реализовать данный многопоток на С#
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 721
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
746
Баллы
113
через общий список с локированием.
Такой много поток, технически реализуемо, есть сайты, заблокированные Роскомнадзором, и многие уже доживают последние месяцы, на мох глазах уже штук 15 крупных сайтов сгинули в никуда, на каждом было новостей от 15к до 30к было.
Я решил об них позаботиться и вот набрал несколько десятков сайтов, которые по моему мнению скоро закроются, решил организовать парсинг, и думаю раз в неделю включать новые новости если есть парсить, вроде все отлично получается, в выходных настройках переключил, сначала один спарсил, потом второй и т.д.
Некоторые сайты на шаред хостах, и в 20 потоков можно уложить сайт или отдаст код 500, хочу парсить все сразу, распределить потоки на каждый сайт по 5 поток примерно, например включил 50 потов и все сайты парсятся, 5 поток на один, 5 потоков на другой и т.д. такое реализуемо?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 721
Баллы
113
Такой много поток, технически реализуемо, есть сайты, заблокированные Роскомнадзором, и многие уже доживают последние месяцы, на мох глазах уже штук 15 крупных сайтов сгинули в никуда, на каждом было новостей от 15к до 30к было.
Я решил об них позаботиться и вот набрал несколько десятков сайтов, которые по моему мнению скоро закроются, решил организовать парсинг, и думаю раз в неделю включать новые новости если есть парсить, вроде все отлично получается, в выходных настройках переключил, сначала один спарсил, потом второй и т.д.
Некоторые сайты на шаред хостах, и в 20 потоков можно уложить сайт или отдаст код 500, хочу парсить все сразу, распределить потоки на каждый сайт по 5 поток примерно, например включил 50 потов и все сайты парсятся, 5 поток на один, 5 потоков на другой и т.д. такое реализуемо?
да
 

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
774
Благодарностей
517
Баллы
93
через общий список с локированием.
Через список не подходит, я думал через перенос файла в отдельную папку, но все равно надо директорию локнуть, на время переноса, но я не нашел как это сделать.
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 721
Баллы
113
Через список не подходит, я думал через перенос файла в отдельную папку, но все равно надо директорию локнуть, на время переноса, но я не нашел как это сделать.
чем список плох ?
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
746
Баллы
113
Последнее редактирование:

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
774
Благодарностей
517
Баллы
93
чем список плох ?
Много папок с картинками, придется под каждую делать список. Мне кажется проще сделать напрямую работу через фалы.

Как такой вариант, будет работать или хрень написал?

C#:
    lstIMG.AddRange(Directory.GetFiles(project.Variables["директория с картинками"].Value,"*.jpg"));

    lock (project.Variables["директория с картинками"].Value)//Так локер сработает или я хрень написал?
    {
    int index = Global.Classes.rnd.Next(lstIMG.Count);
    strIMG = lstIMG[index];
    lstIMG.Clear();
    if (!Directory.Exists(project.Variables["новая директория"].Value + "\temp")) Directory.CreateDirectory(project.Variables["новая директория"].Value + "\temp");
    File.Move(strIMG,project.Variables["новая директория"].Value + "\temp" + Path.GetFileName(strIMG));
    }
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 721
Баллы
113
список один нужен, привязанный к файлу, что бы общий был для всех потоков.
лок у тебя неправильно прописан. надо использовать общие объекты которые объявлены в общем коде, а у тебя локальный объект, который существует только для текущего потока.
суть проста.
1. заходишь в лок
2. чекаешь сколько в списке строк
3. если 0 то заполняешь список путями к файлам и удаляешь из списка строки с текстом _work или _complite
4. берешь первую строку
5. удаляешь первую строку
6. переименовываешь файл что бы появился текст _work в имени
7. выходишь из лока.

работаешь с файлом и в конце удаляешь/перемещаешь файл, либо ставишь в имя файла _complite

в результате у тебя никогда не будут пересекаться файлы между потоками и не будут повторно браться обработанные и обрабатываемые в текущий момент. а так же не будет насиловаться диск ненужными действиями с файлами.
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 685
Благодарностей
4 642
Баллы
113
Зашел в папку.
Взял список файлов.
Из них выбрал один по своему критерию (например, случайный).
Перенес в другую папку.
Сохранил путь для работы с этим файлом в данном потоке

Все эти действия должны быть в коде подряд под одним локом
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 685
Благодарностей
4 642
Баллы
113
lock (project.Variables["директория с картинками"].Value)//Так локер сработает или я хрень написал?
Для локов можно использовать спец. объекты, если свои не создавать
SyncObjects.ListSyncer, SyncObjects.TableSyncer или SyncObjects.InputSyncer. Думаю, в твоем случае будет уместен последний
 
  • Спасибо
Реакции: Dmitriy Ka

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