【发布时间】:2011-08-19 00:24:07
【问题描述】:
我正在处理一个 C# 中的多线程项目,但我控制工作线程的想法并不像我希望的那样容易。
主 GUI 窗口启动时会创建一个线程,这是它正在运行的函数:
private void continueReading()
{
while (true)
{
lock (_lock)
{
while (!startDAQ)
Monitor.Wait(_lock);
startDAQ = false;
logging = true;
daqTaskComponent1.ReadAsync();
}
}
}
现在,当在 GUI 上单击按钮时,startDAQ 设置为 true,并且 _lock 被脉冲以启动调用 ReadAsync() 的线程。
在 Async 的回调函数中,我锁定同一个 _lock 对象并执行一些计算,然后将 startDAQ 设置为 true 并再次脉冲。
这允许我的 Async 函数仅在回调准备好处理更多数据时被调用,这就是它需要的方式。
问题是我需要能够安全地暂停数据收集,方法是让 continueReading 线程在 Monitor.Wait 上暂停,如果在暂停前调用了 ReadAsync,则允许回调完成。
这是当用户再次单击按钮暂停数据收集时我正在运行的代码:
lock (_lock)
{
startDAQ = false;
Monitor.PulseAll(_lock);
while (logging)
Monitor.Wait(_lock);
}
这不能正常工作,我遇到了一些死锁。这是我第一次使用 Monitor 和 Wait/Pulsing 在线程之间发出信号,所以我有点难过,感觉有一种更简单的方法来处理这个问题。感谢您提供任何帮助或建议。
编辑:以下是回调函数的相关代码:
lock (_lock)
{
//Lots of code here that just manipulates the data passed to the callback
startDAQ = true;
logging = false;
Monitor.PulseAll(_lock);
}
添加了我最初粘贴代码时忘记的日志记录布尔值。
【问题讨论】:
-
请解释您的问题是什么。试图获得一个可能是错误的解决方法可能会让人头疼。
-
问题是我的当前代码出现了死锁。我不确定如何使运行循环的线程安全地暂停。我希望用户能够单击一个按钮来启动和停止调用 ReadAsync 的线程。当用户停止线程时,我必须执行一些清理,这会导致回调函数出现问题,这就是为什么我需要在清理发生之前完成任何挂起的 ReadAsync。
-
startDAQ 必须声明为 volatile。
-
我尝试将 startDAQ 和日志记录都声明为 volatile,但似乎没有任何帮助。我已经看到当用户再次单击按钮时它试图锁定时卡住了,并且我看到它在到达 while(logging) 后卡在该锁内的 Monitor.Wait() 上。
标签: c#