C#.Net 4.0 консольное приложение-как остаться в живых, пока все потоки не завершатся? [дубликат]

Возможные Дубликаты:
C#: ожидание завершения всех потоков

У меня есть консольное приложение, которое порождает некоторые потоки, а затем выходит. Каждый поток занимает примерно ~20 секунд. Похоже, что консольное приложение создает потоки, а затем выходит до того, как потоки получат шанс завершить работу.

Как я могу сказать консольному приложению не выходить, пока все потоки, которые он породил, не будут закончили?

7 ответов


нити расплодили для петли? Если да, то параллель.ForEach будет работать:

ParallelOptions options = new ParallelOptions();
                    Parallel.ForEach(items, options, item=>
                    {
// Do Work here
                        }
                    });

вы можете использовать CountDownEvent.

using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static CountdownEvent countdown;

        static void Main(string[] args)
        {
            countdown = new CountdownEvent(1);
            for (int i = 1; i < 5; i++)
            {
                countdown.AddCount(); //add a count for each (BEFORE starting thread .. Thanks, Brian!)
                //do stuff to start background thread
            }
            countdown.Signal(); //subtract your initial count
            countdown.Wait(); //wait until countdown reaches zero
            //done!
        }

        static void backgroundwork()
        {
            //work
            countdown.Signal(); //signal this thread's completion (subtract one from count)
        }
    }
}

пока Thread Не фон-поток (.IsBackground), приложение должно остаться в живых:

static void Main()
{
    Thread thread = new Thread(MoreStuff);
    thread.IsBackground = false;
    thread.Start();
    Console.WriteLine("Main thread exiting");
}
static void MoreStuff()
{
    Console.WriteLine("Second thread starting");
    Thread.Sleep(5000); // simulate work
    Console.WriteLine("Second thread exiting");
}

больше ничего не требуется. Обратите внимание, что ThreadPool будет использовать фоновые потоки; возможно, проблема в том, что вы используете ThreadPool здесь?

Примечание: если второй поток фактически не начался там может быть небольшой гонкой, где он может выйти преждевременно; вы можете захотеть, чтобы ворота потоков начиная с.


можно использовать Thread.Join дождаться завершения потока.


Как вы запускаете потоки? Это действительно зависит, но если вы просто используете класс Thread, то вызовите yourThread[i].Join() из главного потока, чтобы убедиться, что все потоки завершены.

посмотреть в задачи и задачи фабрики обрабатывать вещи намного более аккуратно, чем в прошлые годы.


вызов Thread.Join() на всех потоках, которые вы запускаете после их запуска. Это заблокирует текущий поток, пока поток не будет завершен.


вы, вероятно, должны использовать синхронизацию и ждать, пока любые порожденные потоки завершат свою работу, либо блокируя основной поток вызовами потока.Регистрация или использование сигнализации (например, с помощью монитора или одного из других вариантов).

в качестве альтернативы вы можете просто заставить порожденные потоки работать как потоки переднего плана, установив свойство IsForeground (afaicr). Это сохранит приложение живым, пока потоки не завершатся, но вы все равно увидите окно консоли исчезает по мере выхода основного потока.