今天我遇到了一些奇怪的行为。我有一个使用SerialPort
类访问的串行设备。主应用程序有一些计时器,每秒轮询一次设备进行一些状态更新。在某个时刻,我需要做一些耗时的工作,因此不要阻止我使用Backgroundworker
的GUI。后台工作者需要一次访问同一个串行设备。有时访问工作有时不会。经典的mutli-thread
场景。所以我尝试在将新命令发送到串行设备的函数上使用Mutex。
对于串行设备,我将所有内容放在它自己的类中。在这个类中,我有一个sendCommand()
函数,可以将命令写入设备并使用AutoResetEvent
和OnDataReceived
事件等待答案。函数sendCommand阻塞,直到收到答案或发生超时。然后我在输入sendCommand时添加Mutex
,在所有可能的退出时添加releaseMutex
。仍然无效。
有没有更好的方法来解决这个问题?
谢谢, 托拜厄斯
答案 0 :(得分:1)
我有一个应用程序执行完全相同的操作 - 我所做的是创建了一个串行访问类,每当我调用它(从GUI或我的一个后台线程)时,我会得到以下内容:
private void myFunction(SerialClass myserialobject) {
if (myserialobject == null)
return;
lock (myserialobject) {
// code accessing the serial object
// ...
// when finished, close the lock statement
}
}
我在主线程和需要访问的任何其他线程中都使用了它。它是封锁的,但我相信这是一个封锁声明。
此外,我没有使用OnDataReceived
事件的事件处理程序,而是让我的串行对象在执行任何写操作后执行阻塞读取,这样就可以防止在错误的上下文中接收任何数据。我不确定您的程序是如何设置的,但您可能需要考虑这样做。如果您知道写入端口时希望读取的字节数,则效果最佳;这样你就不必使用Sleep
来确保读取所有数据。
答案 1 :(得分:0)
我通常做的是在循环中运行串行读/写线程,通过定时等待从BlockingQueue读取命令。如果在超时内接收到串行请求对象,则线程执行它,如果等待超时,则线程执行串行设备的轮询。