Как ждать завершения потока, прежде чем продолжить? - PullRequest
8 голосов
/ 10 августа 2008

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

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

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

Ответы [ 3 ]

10 голосов
/ 10 августа 2008

Сколько порядка нужно навязать темам? Если вам нужно, чтобы вся работа, начатая в цикле, завершилась до продолжения кода, но вас не волнует порядок завершения работы в цикле, тогда вызов 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 внутри цикла, результат был бы в основном таким же, как если бы вы вообще не использовали потоки. Каждая итерация тела цикла создаст и запустит поток, но затем немедленно присоединится к нему и будет ждать его завершения.

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

4 голосов
/ 20 августа 2008

Другим способом ожидания завершения потока является использование 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();
}
2 голосов
/ 10 августа 2008

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

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

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

t.Join();
...