【发布时间】:2011-08-03 04:57:45
【问题描述】:
目前我们的应用程序通过串行端口连接到 Arduino。我们发送一些 ASCII 格式的命令,并得到相同的回报。为此,我们有一个命令队列,一个专用于将这些命令写入端口的线程,以及一个专用于读取和处理所有传入回复的线程。类本身负责发送回复,这给了它太多的责任(应该只负责端口操作,而不是业务逻辑)。
我们宁愿以异步方式执行此操作。系统中的任何东西都可以发送带有回调函数和超时的命令。如果串口得到正确回复,则调用回调函数。否则,它会超时并可能调用第二个回调(或者可能是带有 succeeded? 标志的单个回调)。
但是,我们只使用过异步方法(尤其是在 Web 操作中),没有编写过这样的系统。谁能给我们一些关于如何进行的指示?
我们当前的计划是存储这些命令的队列。在任何回复中,如果找到关联的命令(通过比较 ASCII 值),则将其出列并执行回调。计时器将定期检查超时、出列并执行适当的回调。这似乎是一个简单的解决方案,但支持它的代码量正在大幅增加,我们希望确保没有更好的内置解决方案或最佳实践。
编辑:为了进一步澄清,这个特定的类是一个单例(无论好坏),并且有许多其他线程正在运行可以访问它。例如,一个线程可能想要请求传感器值,而另一个线程可能正在控制电机。这些命令及其相关回复不会以线性方式发生;时间可能会颠倒。因此,传统的生产者-消费者模型是不够的;这更像是一个调度程序。
例如,我们称这个单例类为Arduino。 Thread A 正在运行,并且想发送命令"*03",所以它调用Arduino.Instance.SendCommand("*03")。同时,Thread B 发送一个命令"*88",这两个命令都是近实时发送的。稍后,Arduino 的SerialPort.Read() 线程收到*88 的回复,然后收到*03 的回复(即以相反的顺序发送它们)。我们如何允许Thread A 和Thread B 正确阻止等待特定回复的到来?我们假设我们将在每个线程中使用AutoResetEvent,并使用异步回调让我们.Set 它。
【问题讨论】:
标签: c# multithreading asynchronous serial-port