我面临 C#.NET 应用程序中线程之间通信的问题。
希望有人能指导我找到可能的解决方案的正确方向。
我有一个 C#.NET 中的应用程序。它是一个 Windows 窗体应用程序。
我的应用程序有两个线程 - 一个线程是主线程(UI 线程),另一个线程是子线程。我们将子线程称为“workerThread”
应用程序中仅使用一种表单。让我们将此表单称为“MainForm”
子线程在 MainForm 加载时启动(使用表单的“Load”事件处理程序启动线程)
在 MainForm 类中,我有一个名为“stopWork”的变量,它是一个公共布尔变量,它用作指示子线程是否应该继续工作或应该停止的标志
我有另一个类(除了 MainForm 类),其中包含我在子线程中执行的方法。我们将第二个类称为“WorkerClass”。
我将对当前表单(MainForm)的引用传递到“WorkerClass”的构造函数中
我在主窗体中有一个按钮“stop”,如果单击它,则将“stopWork”设置为“true”,然后调用“workerThread.Join()”以等待子线程完成执行。
在子线程中,方法“doWork”不断检查“parentForm.stopWork”内部的状态for环形。如果“stopWork”设置为“true”,则循环中断,随后该方法结束。
现在的问题是,一旦我单击“停止”按钮,应用程序就会挂起。
我粘贴了下面的部分代码,以便更容易理解:
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()”方法被阻止。所以,我认为这是一个“僵局”问题。
我对问题的识别正确吗?或者我错了,问题出在其他地方?
如果这确实是一个僵局,有哪些可能的解决方案可以解决这个问题?
我做了一些谷歌搜索,发现了很多关于线程同步以及如何避免死锁的资源。但我不明白如何将它们专门应用于我的问题。
我非常感谢有关解决此问题的任何帮助或指导。