Многопоточная обработка большого массива через ThreadPool с возможностью остановки - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день! Возникла такая задача. В массиве 200 тыс. строк. Их нужно обработать с помощью довольно быстрой функции с максимальной скоростью. Я использую ThreadPool для обработки:
Листинг программы
  1. foreach (string line in lines)
  2. {
  3. ThreadPool.QueueUserWorkItem(arg =>
  4. {
  5. CheckMulti((object)line);
  6. });
  7. }
Но мне нужно чтобы после выполнения операции появился MessageBox. То есть нужно подождать, пока не завершится обработка всех строк. И здесь такая проблема. Раньше в подобных ситуациях я использовал:
Листинг программы
  1. RunningWorkers = lines.count;
  2. foreach (string line in lines)
  3. {
  4. ThreadPool.QueueUserWorkItem(new WaitCallback(checkMulti), (object)file);
  5. Thread.Sleep(10);
  6. }
  7. //ожидание threadpool
  8. lock (WorkerLocker)
  9. {
  10. while (RunningWorkers > 0)
  11. {
  12. Monitor.Wait(WorkerLocker);
  13. }
  14. }
  15. public void CheckMulti(object line)
  16. {
  17. //обработка строки
  18. ...
  19. //
  20. lock (WorkerLocker)
  21. {
  22. RunningWorkers--;
  23. Monitor.Pulse(WorkerLocker);
  24. }
  25. }
Но получается, что на каждой строчке стоит ожидание Thread.Sleep(10), отчего обработка получается очень медленной. Возможно ли как-то по-другому переписать этот код, чтобы была максимальная скорость и возможность дождаться конца обработки? Варианты с Foreach.Parallel или Task просьба не предлагать, мне нужно именно на ThreadPool.

Решение задачи: «Многопоточная обработка большого массива через ThreadPool с возможностью остановки»

textual
Листинг программы
  1.     public static class ParallelExtender
  2.     {
  3.         public delegate TResult Func<in T, out TResult>(T arg);
  4.         public static TResult[] MapAsync<T, TResult>(this ICollection<T> collection, Func<T, TResult> func)
  5.         {
  6.             var result = new TResult[collection.Count];
  7.             var allDone = new ManualResetEvent(false);
  8.             int completed = 0;
  9.             int i = 0;
  10.             foreach (var item in collection)
  11.             {
  12.                 T t = item;
  13.                 int index = i;
  14.                 ThreadPool.QueueUserWorkItem(_ =>
  15.                 {
  16.                     result[index] = func(t);
  17.                     if (Interlocked.Increment(ref completed) == result.Length)
  18.                         allDone.Set();
  19.                 });
  20.                 i++;
  21.             }
  22.             allDone.WaitOne();
  23.             return result;
  24.         }
  25.     }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.8 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы