2

拥有设备,通过 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){},以同步读取和写入。或者有更好的解决方案,当一个线程正在写入,而其他线程正在读取时,我该如何避免这种情况?

4

2 回答 2

1

锁完成了这项工作。当一个人使用该端口时,另一个人正在等待。除非您将为每个线程或某种端口池使用单独的端口。

于 2013-11-03T15:11:18.483 回答
1

是的,需要锁定。Write() 调用被序列化得很好,通过锁定在设备驱动程序内部来处理。但是,另一个线程在第一个调用 sp.Write() 的线程之前竞争并窃取该线程的响应的可能性不为零。这些几率非常小,这使得在比赛时诊断变得非常困难。测试时你永远不会重现它,这可能每周出错一次。

不,没有简单的更好的解决方案。将所有设备通信只留给一个线程是一种替代方法,但您必须解决每个单独线程的异步问题。

您确实需要修复代码,您不能依赖设备在“interchar_delay”内响应。延迟远大于此,整个send_buffer都需要设备收发和处理。当机器负载过重时,您自己的代码很容易受到垃圾收集器和操作系统交换进程页面的任意长时间延迟。在 Write() 调用之后发生这种情况时,灾难就来了。永远不要考虑让超时时间少于 10 秒。这很好,它应该是例外的。非常支持使用 SerialPort.ReadTimeout 属性,它是由驱动程序实现的,它不会受到那些任意长的延迟的影响。

于 2013-11-03T16:18:09.930 回答