Nutshell: я запускаю поток из своей формы, затем через некоторое время использую метод Join. Это заканчивается, но мое приложение застряло в Присоединении и отказывается признать, что оно закончило присоединение. Что могло бы вызвать это? Моя ветка запускается с помощью кнопки в моей форме и пытается присоединиться ко второй кнопке в той же форме.
Подробнее:
У меня есть приложение, которое использует многопоточность для осуществления связи и обработки чисел. Предполагая, что основная форма является родительским потоком, первым дочерним элементом является Child1. После запуска Child1 устанавливает некоторые связи с внешними устройствами и запускает 2 собственных дочерних потока (Child2 и Child3) для обработки входящих данных.
Когда пользователь решает, что приложение должно прекратить обработку входящих данных, мне нужно, чтобы Child1 завершил работу (чтобы настройки com можно было изменить перед возобновлением, если это необходимо). Я установил событие остановки, и Child1 выходит из своего цикла выполнения, первым делом он уведомляет Child2 и Child3, что они больше не нужны (через другое событие остановки), Child2 и Child3 ожидаются с помощью метода Join в Child1. Это работает просто отлично.
Что не работает, так это то, что форма также использует метод Join для Child1 после установки события остановки, которое побуждает Child1 выйти из цикла выполнения и завершить, это соединение, однако, ждет бесконечно.
Пошаговое руководство. При просмотре приложения я замечаю, что перед использованием Join свойство IsAlive имеет значение true. После того, как я нажал Child1.Join (), я больше не могу получать какую-либо информацию из потока, потому что он находится в "JoinWaitSleep". Однако, если я запускаю цикл while, который заставляет поток формы спать, пока Child1.IsAlive имеет значение true, это работает просто отлично. Является ли моя вторая кнопка частью потока, который не может присоединить к ней Child1?
public void Run()
{ //Known as Child1
//code to setup coms is here
//Launch Builder threads
InsertBackgroundMonitor("Launching Collector Threads");
RunBuilders = true;
//Known as Child2 and Child3
BuildThread1 = new Thread(new ThreadStart(Cam1Builder));
BuildThread2 = new Thread(new ThreadStart(Cam2Builder));
BuildThread1.Start();
BuildThread2.Start();
while (!StopEventHandle.WaitOne(0, true))
{
//// Code that waits for coms and tosses data into lists
}
RunBuilders = false;
//Wait for threads to terminate
BuildThread1.Join();
BuildThread2.Join();
}
private void RunButton_Click(object sender, System.EventArgs e)
{
//Button for running the control thread
ControlThread = new Thread(new ThreadStart(Run));
ControlThread.Start();
}
private void StopButton_Click(object sender, System.EventArgs e)
{
if (btnStop.Enabled)
{ //Button for stopping the control thread
StopEventHandle.Set();
if (ControlThread != null)
{
while (ControlThread.IsAlive)
{
Thread.Sleep(100);
}
//somehow Join did not work
//ControlThread.Join();
}
//Update buttons
btnStart.Enabled = true;
btnStop.Enabled = false;
}
}