C#多线程和串行通信

C#多线程和串行通信,c#,multithreading,thread-safety,serial-port,C#,Multithreading,Thread Safety,Serial Port,今天我遇到了一些奇怪的行为。我有一个使用SerialPort类访问的串行设备。主应用程序有一些计时器,每秒轮询一次设备以进行某些状态更新。在某一点上,我需要做一些耗时的工作,因此不需要阻塞我使用的Backgroundworker的GUI。backgroundworker需要访问同一个串行设备一次。有时通道工作,有时不工作。经典的多线程场景。因此,我尝试在向串行设备发送新命令的函数上使用互斥锁 对于串行设备,我将所有内容都放在它自己的类中。在这个类中,我有一个sendCommand()函数,它将命

今天我遇到了一些奇怪的行为。我有一个使用
SerialPort
类访问的串行设备。主应用程序有一些计时器,每秒轮询一次设备以进行某些状态更新。在某一点上,我需要做一些耗时的工作,因此不需要阻塞我使用的
Backgroundworker
的GUI。backgroundworker需要访问同一个串行设备一次。有时通道工作,有时不工作。经典的
多线程
场景。因此,我尝试在向串行设备发送新命令的函数上使用互斥锁

对于串行设备,我将所有内容都放在它自己的类中。在这个类中,我有一个
sendCommand()
函数,它将命令写入设备,并使用
AutoResetEvent
OnDataReceived
事件等待回答。函数sendCommand会一直阻塞,直到收到应答或超时为止。然后,我在输入send命令时添加了
Mutex
,并在所有可能的出口上添加了
releaseMutex
。还是不行

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

谢谢,
Tobias

我有一个应用程序可以做同样的事情——我所做的是创建一个串行访问类,每当我调用它时(从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
来确保所有数据都已读取。

我通常会在循环中运行串行读/写线程,通过定时等待从阻塞队列读取命令。如果在超时时间内收到串行请求对象,线程将执行该对象;如果等待超时,线程将对串行设备进行轮询

释放互斥?与C#一起工作?只需将整个函数包装在lock()语句中?您是否看到错误消息,或者应用程序是否在等待互斥释放时锁定?您的设备不支持双工通道?您可以发布一些代码吗?特别是你要同步的部分?前提是非常棘手的。最好是推,而不是拉。运行收到响应时处理响应的代码。感谢您的建议。我不知道要接收的字节数。这是一种ASCII类型的协议,其中命令由换行符分隔。在我收到一个空行后,我必须解析并检查我以前收到的内容。它可以是从零到四条数据线。因此,我使用
ondatareed
将所有内容写入缓冲区,直到收到一个空行。然后,我设置了一个
AutoResetEvent
来向我的
SendCommand
例程发送信号来处理数据。
SemdCommand
会一直阻塞,直到收到数据或发生超时。