Я столкнулся с проблемой связи между потоками в приложении C # .NET.
Надеюсь, что кто-то направит меня в правильном направлении относительно возможных решений.
У меня есть приложение на C # .NET. Это приложение для Windows.
Мое приложение имеет два потока: один поток является основным (поток пользовательского интерфейса), а другой - дочерним. Давайте назовем дочерний поток «workerThread»
В приложении используется только одна форма. Пусть эта форма называется «MainForm»
Дочерний поток запускается при загрузке MainForm (для запуска потока использовался обработчик событий формы «Load»)
В классе MainForm у меня есть переменная с именем stopWork, которая является публичной логической переменной и служит в качестве флага, указывающего, должен ли дочерний поток продолжать работать или он должен остановиться
У меня есть другой класс (помимо класса MainForm), который содержит метод, который я выполняю в дочернем потоке. Давайте назовем этот второй класс "WorkerClass".
Я передаю ссылку на текущую форму (MainForm) в конструктор "WorkerClass"
У меня есть кнопка «stop» в главной форме, которая устанавливает «stopWork» в «true», если ее щелкнуть, а затем вызывает «workerThread.Join ()», чтобы дождаться завершения обработки дочерним потоком.
В дочернем потоке метод doWork продолжает проверять состояние «parentForm.stopWork» внутри цикла для . Если для «stopWork» установлено значение «истина», цикл прерывается, а затем метод завершается.
Теперь проблема в том, что после нажатия кнопки «Стоп» приложение зависает.
Я вставляю части кода ниже, чтобы его было легче понять:
public partial class MainForm : Form
{
Thread workerThread = null;
ThreadStart workerThreadStart = null;
WorkerClass workerClass = null;
public bool stopWork = true;
/*.......... some code ............*/
private void MainForm_Load(object sender, EventArgs e)
{
workerThreadStart = new ThreadStart(startWork);
workerThread = new Thread(workerThreadStart);
stopWork = false;
workerThread.Start();
}
private void startWork()
{
workerClass = new WorkerClass(this);
}
private void buttonStop_Click(object sender, EventArgs e) //"stop" button
{
if (workerThread != null)
{
if (workerThread.IsAlive == true)
{
stopWork = true;
workerThread.Join();
}
}
}
/*.......... some more code ............*/
}
public class WorkerClass
{
MainForm parentForm=null;
/*......... some variables and code ........*/
public WorkerClass(MainForm parentForm)
{
this.parentForm=parentForm;
}
/* .............. some more code ...........*/
public void doWork()
{
/*.......... some variables and code ...........*/
for(int i=0;i<100000;i++)
{
// ** Here is the check to see if parentForm has set stopWork to true **
if(parentForm.stopWork==true)
break;
/*......... do some work in the loop ..........*/
}
}
/********* and more code .........*/
}
Думаю, я знаю, в чем проблема.
Проблема заключается в том, что метод doWork в дочернем потоке пытается получить доступ к переменной stopWork в родительской форме, когда родительская форма уже заблокирована путем вызова метода workerThread.Join (). Итак, я думаю, что это проблема "тупика".
Прав ли я в определении проблемы? Или я не прав и проблема кроется где-то еще?
Если это действительно тупик, каковы возможные решения этой проблемы?
Я немного погуглил и нашел много ресурсов о синхронизации потоков и о том, как избежать тупиков. Но я не мог понять, как применить их конкретно к моей проблеме.
Буду очень признателен за любую помощь или руководство по решению этой проблемы.