gpt4 book ai didi

c# - SerialPort.Read(....) 不遵守 ReadTimeOut

转载 作者:行者123 更新时间:2023-11-30 14:14:44 26 4
gpt4 key购买 nike

在一些与支付终端通信的遗留代码中发现了一个错误。

就在开始新的支付之前,代码尝试清除 SerialPort 的内部读取缓冲区。

我将代码精简到最低限度。它使用 .NET SerialPort 类型。设置了 50 毫秒的读取超时。然后它读取 512 个字节并继续这样做,直到不再读取任何字节或直到抛出 TimeoutException。

我们添加了一堆日志记录,它表明对第一个 Read(...) 方法的调用有时需要 10 - 15 分钟,即使超时为 50 毫秒。然后抛出 TimeoutException 并继续应用程序。但是在 Read(...) 期间应用程序挂起。

这并不总是会发生,Windows 2000 机器由于某种原因似乎更容易出现此错误。

public class Terminal
{
private SerialPort _serialPort = new SerialPort();

public void ClearReadBuffer()
{
try
{
_serialPort.ReadTimeout = 50;
int length;
do
{
var buffer = new byte[512];
length = _serialPort.Read(buffer, 0, 512);
} while (length > 0);
}
catch (TimeoutException) {}
}
}

感谢任何帮助。

PS:大多数错误报告来自 W2K 机器,其中设备连接到 EdgePort,模拟一组虚拟 COM 端口。它的驱动程序创建了一堆(8 个左右)本地 COM 端口。

但我们也有来自 Windows 7 的报告。如果我们直接将设备连接到 PC(没有 EdgePort),我们也可以重现该问题。但是不那么频繁,当它发生时,延迟不是 10 分钟,而是更像是 1 - 2 分钟。

更新:尝试了很多方法来解决这个问题。很难重现,但在现场经常发生,因为它分布在数千台 PC 上。实际上用另一个开源版本替换了 .NET 2.0 SerialPort 类型。在一台 PC 上正常工作,我们实际上可以在 60-70% 的时间内重现它。但遗憾的是,在生产中的试点测试期间,问题仍然继续出现。

支付终端的代码是几年前编写的,我将其移植到另一个应用程序中。在移植期间,我重构了一些代码,但保留了原来的功能。与终端通信时,代码将:

  1. 从线程池中触发另一个线程
  2. 发送消息到设备
  3. 从串行端口读取,直到收到响应或发生超时。

与此同时,主线程有一个 while 循环,其中包含一个 Thread.Sleep(50) 和一个 Application.DoEvents() 调用(糟糕!)。我从中重构了整个“等待循环”并使用了 WaitHandle (AutoResetEvent/ManualResetEvent)。我只是等到这个句柄被设置。工作没有问题,但在某些 PC 上,所有串行端口通信都会卡住几分钟,直到触发它。重新启用 Application.DoEvents() 的工作方式,问题就消失了。

不幸的是,它仍然在那里,这对我来说是一个谜,为什么这里需要它以及为什么它会导致如此严重的副作用。该应用程序支持 5 种其他类型的串行端口设备。与这些设备通信从来不需要这样的东西。

最佳答案

也许在端口的“要读取的字节数”上添加测试可能有助于避免编码错误的驱动程序:

length = (_serialPort.BytesToRead > 0) ? _serialPort.Read(buffer, 0, 512) : 0;

更好的是,使用

_serialPort.DiscardInBuffer();

相反!

关于c# - SerialPort.Read(....) 不遵守 ReadTimeOut,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11340513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com