Задать вопрос

Как правильно дождаться выполнения всех потоков, созданных в цикле?

Пожалуйста. подскажите:
Есть потоки, создаваемые в цикле. Все они должны выполняться параллельно, но при этом дальнейшее выполнение кода после потока должно происходить только по завершении всех этих потоков.
Код примерно такой:

List<Thread> lstThread = new List<Thread>();
 while (currentItemMonth <= this.lastMonth)
{

                            GeneratorItemSheet g = new GeneratorItemSheet(sh);
                            Thread myThread = new Thread(new ThreadStart(g.GenerateMonthSheet));
                            myThread.Start();
                            lstThread.Add(myThread);

                            //Переходим на следующий месяц
                            currentItemMonth = currentItemMonth.AddMonths(1);
}

foreach (Thread thread in lstThread)
{
      if (thread.IsAlive) thread.Join();
}


Т е складываю все потоки в лист, а потом циклом делаю им join.
Вопрос: Правильный ли это способ или надо как-то иначе. Просто у меня уходит в зависание, понять бы, это оттого, что идея в принципе неправильная или идея правильная, но хромает реализация внутри метода, вызываемого в потоке.
  • Вопрос задан
  • 4348 просмотров
Подписаться 5 Простой Комментировать
Помогут разобраться в теме Все курсы
  • OTUS
    C# Developer. Professional
    6 месяцев
    Далее
  • Ulearn.me
    Основы программирования на примере C#. Часть 1
    1 неделя
    Далее
  • Software-testing.ru
    Программирование на C# для тестировщиков
    10 недель
    Далее
Пригласить эксперта
Ответы на вопрос 3
@kttotto
пофиг на чем писать
У Вас не правильный подход. Во первых забудьте про Thread и используйте TPL. Во вторых для распараллеливания запросов в цикле есть замечательный метод Parallel.ForEach. В третьих для ожидания выполнения всех параллельных задач есть Task.WaitAll.
В общем Вы можете создать список Task-ов и запихнуть их в Task.WaitAll, но лучше пройдитесь параллельным форичем по Вашему периоду и внутри запускайте Ваши методы. Код за форичем будет ожидать завершения всех потоков в цикле.
Ответ написан
tomnolane
@tomnolane
профессиональный разработчик
оффтоп
люди подписались чисто поглазеть или поржать?

вы уверены, что вам нужен Thread?
Task или Thread в C#.NET 4.0 WPF? ( Павел Елизарьев доступно описал разницу в ответе)
я бы использовал Task для начала, т.к. есть такая замечательная штука, как пулл потоков (подзабыл как на английском называется) который лучше обычного программиста (автоматически) понимает, когда и кто закончил, сколько есть свободных, сколько нужно и что с ним дальше делать. И нужно у вас в коде делать акцент не на блокирование/синхронизацию потоков (оставьте их в покое - чем быстрее сделают, тем лучше), а использовать вот такую простую штуку: Оператор lock
а зависание происходит потому, что вы и основной поток блокируете.
Ключевое слово lock не позволит ни одному потоку войти в важный раздел кода в тот момент, когда в нем находится другой поток. При попытке входа другого потока в заблокированный код потребуется дождаться снятия блокировки объекта.
Ответ написан
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Написано все правильно.

Чтобы понять, в чем проблема, давайте попробуем внутри метода "GenerateMonthSheet" вывести в лог две записи: начало работы, окончание работы (с указанием месяца).

И посчитаем, сколько стартануло, сколько завершило работу.

P.S. А как вы номер месяца в генератор передаете? И откуда берется переменная "sh"?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы