【发布时间】:2011-07-28 05:36:57
【问题描述】:
我遇到了 C#.NET 应用程序中线程之间的通信问题。 希望有人能就可能的解决方案指导我正确的方向。
我有一个 C#.NET 应用程序。它是一个 Windows 窗体应用程序。 我的应用程序有两个线程 - 一个线程是主线程(UI 线程),另一个是子线程。让我们称子线程为“workerThread” 应用程序中只使用了一个表单。让我们将此表单称为“MainForm”
子线程在 MainForm 加载时启动(使用表单的“Load”事件处理程序启动线程)
在 MainForm 类中,我有一个名为“stopWork”的变量,它是一个公共布尔变量,它用作指示子线程是应该继续工作还是应该停止的标志
我有另一个类(除了 MainForm 类),它包含我在子线程中执行的方法。让我们将这第二类称为“WorkerClass”。 我将对当前表单(MainForm)的引用传递给“WorkerClass”的构造函数
我在主窗体中有一个“停止”按钮,如果单击它,它将“stopWork”设置为“true”,然后调用“workerThread.Join()”以等待子线程完成执行。
在子线程中,方法“doWork”在for循环中不断检查“parentForm.stopWork”的状态。如果“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()”方法被阻止。所以,我认为这是一个“死锁”问题。
我在确定问题方面是否正确?还是我错了,问题出在其他地方?
如果这确实是一个死锁,有什么可能的解决方案来解决这个问题?
我做了一些谷歌搜索,发现了很多关于线程同步以及如何避免死锁的资源。但我不明白如何将它们专门应用于我的问题。
非常感谢任何有关解决此问题的帮助或指导。
【问题讨论】:
-
我想查看您的工作线程类的一部分,看看它如何检测是否已请求停止工作。你能把它包括进去吗?
-
您是否正在从您的线程更新 GUI?
-
@Lasse V. Karlsen:是的,我正在从子线程更新 GUI。我在富文本框控件上调用 Invoke 以将消息写入 UI。
标签: c# multithreading deadlock thread-synchronization