在我的 .Net 控制台应用程序中,我使用以下方法将少量字节(大约 20 个)写入串行端口,然后读取响应(同样不超过 20 个字节)。它用于与外部硬件设备通信 - 向其发送数据请求并返回请求的值。
我已经删除了多余的代码、端口初始化、变量声明等,但你仍然可以看到它在做什么:-
var sw = new Stopwatch();
sw.Start();
// Write the "request" bytes.
_port.Write(buffer, 0, buffer.Length);
Console.WriteLine("After write: {0}", sw.ElapsedMilliseconds);
sw.Restart();
// Wait for response, but timeout after 100ms.
var timeoutCount = 0;
while (_port.BytesToRead == 0 && timeoutCount < 100)
{
Thread.Sleep(1);
timeoutCount++;
}
Console.WriteLine("Waited: {0}, #loops: {1}", sw.ElapsedMilliseconds, timeoutCount);
if (_port.BytesToRead == 0)
{
// Timed-out..
return null;
}
// Read the response.
var receivedData = new byte[_port.BytesToRead];
_port.Read(receivedData, 0, receivedData.Length);
return receivedData;
我的应用程序以紧密(几乎连续)的循环调用上述代码。你会注意到我添加了几个 Console.WriteLines 来输出一些时间,我看到非常一致的数字,如下所示:-
After write: 0 Waited: 14, #loops: 1 After write: 0 Waited: 14, #loops: 1 After write: 0 Waited: 14, #loops: 1 ...and so on...
显然,写入发生得非常快,响应也很快到达,因为应用程序只通过while
循环一次,尽管我对为什么它只执行一次时显示 14ms 感到困惑Thread.Sleep(1)
。
更奇怪的是,如果我在 PC 上做其他事情,比如打开另一个窗口,运行 Chrome,或者只是移动鼠标,那么我会看到这样的数字:-
After write: 0 Waited: 4, #loops: 5 After write: 0 Waited: 2, #loops: 3 After write: 0 Waited: 2, #loops: 3 After write: 0 Waited: 1, #loops: 2 After write: 0 Waited: 3, #loops: 4
这更像是我对串行端口代码(例如我的)的期望,而不是我在 PC“空闲”时看到的神秘 14 毫秒。关于发生了什么的任何想法?
这给我带来了一个问题,因为我的应用程序需要每 100 毫秒执行大约 12 次写入/读取。您可以从第二组时间(每组几毫秒)中看到,这很容易实现,但是当 PC 处于“空闲”状态时,每次写入/读取需要 14 毫秒,导致我的应用程序经常丢失数据(在外部更新设备每 100 毫秒)。