Как дождаться завершения потока, прежде чем продолжить?
-
08-06-2019 - |
Вопрос
У меня есть некоторый код для запуска потока в .NET CF 2.0:
ThreadStart tStart = new ThreadStart(MyMethod);
Thread t = new Thread(tStart);
t.Start();
Если я вызываю это внутри цикла, элементы полностью выходят из строя.Как ввести ожидание после t.Start()
, чтобы работа над потоком завершилась до продолжения кода?Будет ли BeginInvoke / EndInvoke лучшим вариантом для этого, чем создание потоков вручную?
Решение
Какой порядок вам нужно навести в потоках?Если вам просто нужно завершить всю работу, начатую в цикле, до продолжения кода, но вас не волнует порядок завершения работы в цикле, то ответом будет вызов 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 внутри цикла, результат был бы в основном таким же, как если бы вы вообще не использовали потоки.Каждая итерация тела цикла создавала бы и запускала поток, но затем немедленно присоединялась бы к нему и ждала его завершения.
Если отдельные потоки выдают какой-то результат (например, записывают сообщение в журнал), то сообщения все равно могут отображаться не по порядку, потому что нет координации между потоками.Можно заставить потоки выводить свои результаты по порядку, координируя их с Монитором.
Другие советы
Другим способом ожидания завершения потока является использование 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();
}
Если я правильно это читаю, вы запускаете рабочие элементы в нескольких потоках, но вы обеспокоены тем, что потоки завершаются не по порядку, и предпочли бы подождать, пока каждый поток завершится в том порядке, в котором они были запущены?
Если это так, то я не уверен, зачем вы создаете поток для каждого рабочего элемента.Может быть, вы могли бы расшириться?
Если вам действительно нужно было дождаться завершения потока, вы могли бы просто сделать:
t.Join();