【问题标题】:C# multiple threads and serial communicationC#多线程和串行通信
【发布时间】:2013-07-06 02:48:06
【问题描述】:

今天我遇到了一些奇怪的行为。我有一个使用SerialPort 类访问的串行设备。主应用程序有一些计时器,每秒轮询一次设备以获取某些状态更新。在某些时候,我需要做一些耗时的工作,因此不要阻止我使用Backgroundworker 的 GUI。后台工作者需要一次访问相同的串行设备。有时访问工作有时不工作。经典的mutli-thread 场景。所以我尝试在将新命令发送到串行设备的函数上使用互斥锁。

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

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

谢谢, 托比亚斯

【问题讨论】:

  • 释放互斥量?使用 C#?只需将整个函数包装在 lock() 语句中?
  • 您看到错误消息还是应用程序锁定等待互斥锁释放?
  • 您的设备不支持双工通道?
  • 你能贴一些代码吗?特别是您要同步的部分?
  • 前提很棘手。最好通过推而不是拉来完成。运行收到响应时处理响应的代码。

标签: c# multithreading thread-safety serial-port


【解决方案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 来确保读取所有数据。

【讨论】:

  • 感谢您的建议。我不知道要接收的字节数。它是一种 ASCII 类型的协议,其中命令由换行符分隔。在我收到一个空行后,我必须解析并检查我之前收到的内容。它可以是从零数据线到四个数据线的任何东西。所以我使用OnDataReeived 并将所有内容写入缓冲区,直到收到空行。然后我设置了一个AutoResetEvent 来通知我的SendCommand 例程来处理数据。 SemdCommand 会阻塞,直到收到数据或发生超时。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多