Дождитесь окончания двух потоков - PullRequest
3 голосов
/ 27 февраля 2009

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

Я мог бы использовать bgndworker и Sleep Spinner, который проверяет как IsBusy рабочих bgnd, но я думаю, что есть лучший способ.

EDIT Еще несколько требований:

  • В основном потоке есть еще какая-то работа (например, GUI).
  • Два порожденных потока должны иметь возможность сообщать об исключениях и возвращать значения результатов

Ответы [ 6 ]

10 голосов
/ 27 февраля 2009

Быстрый пример с использованием Thread.Join ();

        Thread t1 = new Thread(new ThreadStart(delegate()
        {
            System.Threading.Thread.Sleep(2000);
        }));

        Thread t2 = new Thread(new ThreadStart(delegate()
        {
            System.Threading.Thread.Sleep(4000);
        }));

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

РЕДАКТИРОВАТЬ Еще 3 примера с использованием ручек ожидания:

            ManualResetEvent[] waitHandles = new ManualResetEvent[]{
            new ManualResetEvent(false),
            new ManualResetEvent(false)
        };

        Thread t1 = new Thread(new ParameterizedThreadStart(delegate(object state)
        {
            ManualResetEvent handle = (ManualResetEvent)state;
            System.Threading.Thread.Sleep(2000);
            handle.Set();
        }));

        Thread t2 = new Thread(new ParameterizedThreadStart(delegate(object state)
        {
            ManualResetEvent handle = (ManualResetEvent)state;
            System.Threading.Thread.Sleep(4000);
            handle.Set();
        }));

        t1.Start(waitHandles[0]);
        t2.Start(waitHandles[1]);

        WaitHandle.WaitAll(waitHandles);

        Console.WriteLine("Finished");
5 голосов
/ 27 февраля 2009

См. Ответы на этой теме . Мне нравится эта опция ; -p

Forker p = new Forker();
p.Fork(delegate { DoSomeWork(); });
p.Fork(delegate { DoSomeOtherWork(); });
p.Join();

Повторное возвращение значений / отчетов об исключениях - просто сделайте так, чтобы каждый разветвитель делал это как обратный вызов в конце логики ... (вы можете использовать захваченные переменные для передачи состояния в обе вилки, включая общий регистратор и т. Д.) 1008 *

3 голосов
/ 27 февраля 2009
thread1.Join();
thread2.Join();
1 голос
/ 27 февраля 2009

Вы не можете ждать финиша и использовать GUI. Наилучшим подходом для этого является порождение потоков и использование событий для взаимодействия с GUI. Помните, что в обработчике событий вы не можете изменять управление. Вместо того, чтобы делать это напрямую, используйте метод Invoke.

1 голос
/ 27 февраля 2009

В дополнение к другим ответам ... одна альтернатива «запустить два потока и дождаться окончания обоих» - это «запустить один поток и выполнить одну работу самостоятельно, затем подождать, пока другой поток не закончить».

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

РЕДАКТИРОВАТЬ: Если основной поток является потоком пользовательского интерфейса, вы не должны блокировать другие потоки, заканчивая - вы должны (IMO) заставить их перезвонить основному потоку после завершения. Таким образом, у вас все равно будет отзывчивый пользовательский интерфейс во время их выполнения.

0 голосов
/ 27 февраля 2009

WaitHandle.WaitAny твой друг. Это позволяет вам ожидать сигнала от нескольких потоков или других объектов.

http://msdn.microsoft.com/en-us/library/tdykks7z.aspx

EDIT:

На самом деле, WaitHandle. WaitAll - это то, что вы хотите, а не WaitAny.

http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitall.aspx

EDIT:

Метод Join, о котором некоторые упоминают, в порядке, но один недостаток состоит в том, что это не полностью атомарная операция. Это может или не может быть важно для вас, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...