1

Как на C# многопоточно обрабатывать данные из списка(очереди)?
Есть список url, с которых надо загрузить данные и их обработать.
Как правильно организовать код,что б создалось например только 10 потоков и каждый поток брал ссылку из списка,удалял её в списке или очереди,загружал данные и как выполнит действия-забирал следующий элемент списка. Ну и так,что б элемент списка блокировался на время доступа другого потока.

Как организовать это? Читаю семафоры,мьютексы,но пока не вник в это.


подкорректировал :
Я хотел многопоточность изначально, но лучше совместить с асинхронностью. То-есть нет смысла ждать ответ от удалённого сервера. Если в главном потоке делать, то он подвиснет. По-этому сдлав асинхронно- сам поток не будет ждать, когда будет ответ от сервера. Но на одном потоке выигрыша не будет. Если сразу запускаем например 10 потоков, то мы посылаем 10 запросов и ждём(внутри потока асинхронность используем и даже каждый десятый поток не напрягаем в момент ожидания,но асинхронность я могу сделать,а вот многопоточность в очереди пока что не могу),потом каждый поток,получив данные,выполняет действия и затем переходит к следующей порции. То-есть потоки не создаются миллион раз. Они создались сразу и выполняют задачи из очереди.

Создать 10 потоков и сказать каждому -> async GetMyData_and_Save_Data()

,где метод GetMyData_and_Save_Data() берёт ссылку из очереди , качает асинхронно(ну скачивание то я сделаю,это не сложно), ну и потом обрабатывает асинхронно, а потом повторяет, то-еть находится в цикле while, а как очередь будет пуста, то вылетает с метода и поток уничтожается.

Спасибо

Rakzin Roman
  • 5,720
  • Кажеться семафоры и мьютексы это не для C#. Поделить список на 10 (обстрактно), и запустите 10 потоков с частями списка. На самом деле, потоков разумно делать не более чем колличество процессоров, или кратное этому числу. Таски тут лучше не применять, не даст выигрыша во времени и производительности. – NewView Sep 04 '18 at 13:03
  • 2
    Смущают метки: зачем pthread и android-asynctask? К тому же async-await означает асинхронность, а это не совсем то же, что многопоточность. В общем, приведите более точный пример того, что нужно сделать. – Alexander Petrov Sep 04 '18 at 13:04
  • @AlexanderPetrov исправил. На телефоне нечайно близлежащие выбрал. И так 2 раза – Rakzin Roman Sep 04 '18 at 13:15
  • @NewView ну как я понял,выигрыш в данном случае будет,если потоков более,чем ядер/процессоров. Так как узпое место,это ожидание удалённого сервера – Rakzin Roman Sep 04 '18 at 13:16
  • 2
    Запуск каждого потока это тяжёлая и время емкая операция, если обрабатываемые данные малы, то выигрыша по времени и производительности можно не получить вообще. А даже наоборот, замедлить выполнение. – NewView Sep 04 '18 at 13:18
  • Сервера в списке разные? Если есть одинаковые, то используйте "keep-alive" без сброса соединения, не нужно будет лишний раз переподключаться к серверу. – Геннадий П Sep 04 '18 at 13:26
  • Пишу с телефона, потому не ручаюсь за правильность, но var parsed = urlList.Parallel().WithDegreeOfParallelism(10).Select(url=>parser.Parse(url)).ToList(); распарсит вам ваши урлы параллельно в 10 потоков и сложит результат в список. – tym32167 Sep 04 '18 at 15:59
  • Ограничиваем количество потоков - хотя откуда у вас число 10? И почему бы пулу потоков самому не решить сколько выделить потоков? – tym32167 Sep 04 '18 at 16:04
  • И, я бы на вашем месте изучил разницу между многопоточностью и асинхронностью. Важно понимать, что чтобы качать параллельно и асинхронно 10 урлов не обязательно занимать 10 потоков – tym32167 Sep 04 '18 at 16:08
  • @АндрейNOP ну это очень спорный момент, почему вы решили, что это дубликат именно prod/cons? Тут задачу можно решить разными способами, оч спорно в общем – tym32167 Sep 04 '18 at 16:26
  • @tym32167, как хотите, переоткрыл – Андрей NOP Sep 04 '18 at 16:52
  • Роман, судя по активности в вашей теме: есть много комментариев и есть ответы - народ рвется в бой и хочет вам помочь. Но все мы ждем уточнения вашего сценария. Повторю: асинхронность != многопоточность. Если проблема в скачивании, то это IO-операции и тут нужна асинхронность. Если проблема в обработке данных, то это CPU-нагрузка и тут нужна многопоточность. Так что опишите точно, что вам нужно. Возможно, нужно совместить и то, и другое. – Alexander Petrov Sep 05 '18 at 13:02
  • @"Alexander Petrov" спасибо. Я хотел многопоточность изначально, но лучше совместить с асинхронностью. То-есть нет смысла ждать ответ от удалённого сервера. Если в главном потоке делать, то он подвиснет. По-этому сдлав асинхронно- сам поток не будет ждать, когда будет ответ от сервера. Но на одном потоке выигрыша не будет. Если сразу запускаем например 10 потоков, то мы посылаем 10 запросов и ждём(внутри потока асинхронность используем и даже каждый десятый поток не напрягаем в момент ожидания),потом каждый поток,получив данные,выполняет действия и затем переходит к следующей порции. – Rakzin Roman Sep 05 '18 at 13:47
  • сколько хостов надо опросить? 2) какой объем данных?
  • – Vasek Sep 05 '18 at 16:00