2013-07-05 74 views
0

今天我遇到一些奇怪的行为。我有一个串行设备,我使用SerialPort类访问。主应用程序有一些定时器每秒轮询一次设备的状态更新。在某个时候,我需要做一些耗时的工作,因此不要阻止我使用Backgroundworker的GUI。后台工作者需要一次访问相同的串行设备。有时访问有时不起作用。经典mutli-thread方案。所以我尝试在发送新命令到串口设备的函数上使用Mutex。C#多线程和串口通讯

对于串口设备,我把所有东西放在它自己的类中。在这个类中,我有一个sendCommand()函数,它将命令写入设备,并使用AutoResetEventOnDataReceived事件来等待答案。 sendCommand函数阻塞,直到接收到答案或发生超时。然后,我在所有可能的出口处输入sendCommand和releaseMutex时添加了Mutex。仍然不起作用。

有没有更好的方法来处理这个问题?

感谢, 托比亚斯

+0

releaseMutex?使用C#?只需将整个函数包装在一个lock()语句中? –

+0

您是否看到错误消息或应用程序是否锁定,等待互斥锁释放? –

+0

您的设备不支持双工通道? – Suhan

回答

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来确保所有数据都被读取。

+0

谢谢你的建议。我不知道要接收的字节数。这是一个ASCII类型的协议,其中命令由换行符分隔。收到空行后,我必须解析并检查之前收到的内容。它可以是从零到四的任何数据。所以我使用'OnDataReeived'并将所有内容写入缓冲区,直到我收到一个空行。然后我设置一个'AutoResetEvent'来发信号通知我的'SendCommand'例程来处理数据。 'SemdCommand'阻塞,直到收到数据或发生超时。 – thefloe

0

我通常所做的是在循环中运行串行读/写线程,以定时等待的方式从BlockingQueue读取命令。如果在超时时间内收到一个串行请求对象,则线程执行它,如果等待超时,线程将执行对串行设备的轮询。