0

我正在编写一个多线程应用程序,其中一个线程锁定串行端口并连续发送命令并在循环中使用 SerialPort.Write(command) 和 SerialPort.ReadLine() 获取响应,直到它获得一个特定命令的“OK”响应。

线程是否有可能在 ReadLine() 调用期间切换并导致 TimeOutException。

我将超时设置为 2000 毫秒。

程序运行几分钟(大约 5 - 10)后,我有随机的 TmeOutExceptions

23332   10:14:23 AM AutoLoader.WinS IRP_MJ_WRITE    Serial0 SUCCESS Length 9: STG|4.5.. 
23336   10:14:23 AM AutoLoader.WinS IRP_MJ_READ Serial0 SUCCESS Length 1: O 
23339   10:15:54 AM AutoLoader.WinS IRP_MJ_WRITE    Serial0 SUCCESS Length 7: GTSNS..   
23342   10:15:54 AM AutoLoader.WinS IRP_MJ_READ Serial0 SUCCESS Length 3: K..   
23347   10:15:54 AM AutoLoader.WinS IRP_MJ_WRITE    Serial0 SUCCESS Length 7: GLSTS..   
23351   10:15:54 AM AutoLoader.WinS IRP_MJ_READ Serial0 SUCCESS Length 1: O 
23355   10:15:54 AM AutoLoader.WinS IRP_MJ_READ Serial0 SUCCESS Length 3: K..

上午 10 点 14 分 23 秒后,我得到了一个被我抑制的 TimeOutException。

                    while (response != "OK")
                    {
                        Thread.Sleep(1000);

                        _alComm.SendString("SSD|" + CurrentData.MeasuredDepthReturns + Environment.NewLine);
                        response = _alComm.ReceiveString(2000);

                        _alComm.SendString("STG|" + CurrentData.AvgGas + Environment.NewLine);
                        response = _alComm.ReceiveString(2000);

                        _alComm.SendString("GTSNS\r\n");
                        response = _alComm.ReceiveString(2000);
                        SetSamplingTimePercent(response);
                    }

public void SendString(string sDataToSend)
{
    if (sDataToSend == "")
        return;

    try
    {
        AlPort.Write(sDataToSend);
    }
    catch (Exception ex)
    {
        //MessageBox.Show(ex.ToString(), "Error");
    }
}


public string ReceiveString(int timeOut)
{
    string inString = null;
    try
    {
        // set read timeout
        AlPort.ReadTimeout = timeOut;
        inString = AlPort.ReadLine();
    }
    catch (TimeoutException ex)
    {
        return string.Empty;
    }

    return inString;
}
4

1 回答 1

1

A ReadLine(或与此相关的任何 I/O)将导致上下文切换,直到它被服务。现在,我看到的方式有两种可能性:

  1. 要么线程一直被操作系统挂起,直到超时结束并且抛出异常,要么
  2. 您一直处于挂起状态,直到 I/O 得到服务,此时操作系统很可能会立即唤醒您的线程并抢占其他线程以允许您的代码运行。请记住,任何现代操作系统都为 I/O 绑定线程提供了慷慨的优先级提升。
于 2012-04-24T15:52:41.453 回答