Как ждать завершения потока, прежде чем продолжить?

У меня есть код для запуска потока на .NET CF 2.0:

ThreadStart tStart = new ThreadStart(MyMethod);
Thread t = new Thread(tStart);
t.Start();

Если я вызову это в цикле, то элементы полностью выйдут из строя. Как ввести ожидание после t.Start(), чтобы работа над потоком завершилась до продолжения кода? Будет ли BeginInvoke / EndInvoke лучшим вариантом для этого, чем создание потоков вручную?

9.08.2008 20:00:37
3 ОТВЕТА
РЕШЕНИЕ

Сколько порядка нужно навязать темам? Если вам нужно, чтобы вся работа, начатая в цикле, завершилась до продолжения кода, но вас не волнует порядок завершения работы в цикле, тогда вызов Join является ответом. Чтобы добавить больше деталей к ответу Кевина Кенни, вы должны вызвать Join вне цикла. Это означает, что вам понадобится коллекция для хранения ссылок на созданные вами потоки:

// Start all of the threads.
List<Thread> startedThreads = new List<Thread>();
foreach (...) {
  Thread thread = new Thread(new ThreadStart(MyMethod));
  thread.Start();
  startedThreads.Add(thread);
}

// Wait for all of the threads to finish.
foreach (Thread thread in startedThreads) {
  thread.Join();
}

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

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

12
23.05.2017 12:25:36

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

Если это так, то я не уверен, почему вы создаете поток для каждого рабочего элемента. Может быть, вы могли бы расширить?

Если вам нужно дождаться завершения потока, вы можете просто сделать:

t.Join();
4
24.11.2013 07:38:55

Другой способ ожидания завершения потока - использование AutoResetEvent.

private readonly AutoResetEvent mWaitForThread = new AutoResetEvent(false);

private void Blah()
{
    ThreadStart tStart = new ThreadStart(MyMethod);
    Thread t = new Thread(tStart);
    t.Start();

    //... (any other things)
    mWaitForThread.WaitOne();
}

private void MyMethod()
{
     //... (execute any other action)
     mWaitForThread.Set();
}
4
31.08.2015 16:32:46