拥有设备,通过SerialPort类从中获取数据。 这是我的方法:
public WriteAndRead(){
...
sp.Write(send_buffer.ToArray(), 0, send_buffer.Count);
do
{
if (sp.BytesToRead > 0)
{
ret_val = sp.ReadByte();
done = true;
}
else
ret_val = -1;
} while ((!done) && ((Environment.TickCount - char_tmo) < interchar_delay));
...
}
所以我想从其他线程中调用它。 我应该将这部分代码包装到 lock(sp){} ,以同步读写。或者有一个更好的解决方案,当一个线程正在写入时,我可以避免什么情况,以及从中读取其他内容?
答案 0 :(得分:1)
Lock完成这项工作。当一个使用端口时,另一个正在等待。除非您为每个线程或端口池使用单独的端口。
答案 1 :(得分:1)
是的,需要锁定。 Write()调用被很好地序列化,通过锁定设备驱动程序来处理。但是有另外一个线程在第一个调用sp.Write()并且窃取该线程的响应之前的非零赔率。那些赔率非常小,这使得 比赛时诊断成为一个非常难的问题。测试时你永远不会重现它,这可能是每周一次。
不,没有简单的更好的解决方案。将所有设备通信保留为仅一个线程是另一种选择,但您必须解决每个单独线程的异步问题。
您确实需要修复代码,您不能依赖于“interchar_delay”内的设备响应。延迟远大于此,整个send_buffer需要由设备发送和接收并进行处理。当您的机器负载很重时,垃圾收集器和操作系统会交换您的进程页面,您自己的代码很容易受到任意长时间的延迟。在Write()调用之后发生灾难时会发生灾难。永远不要考虑超时不到10秒。这很好,它应该是特殊的。非常强烈支持使用SerialPort.ReadTimeout属性,它由驱动程序实现,它不会受到那些任意长时间延迟的影响。