串口通信之超时

  超时分串口读超时和串口写超时,主要是读超时,即ReadTimeout与Read方法之间的超时。下面谈谈他们之间的意义和实现。

  Read方法是阻塞的,它一直在读串口接收缓冲区中的数据,如果接收缓冲区有数据,Read方法则返回一个或多个字节数据;如果Read方法在等待ReadTimeout毫秒时间内,串口接收区一直没有任何数据,则Read方法将甩ExceptionTimeout异常。注意,Read(outBuf, offset, count)阻塞读取的不是非等到count个字节数据,而是当前接收缓冲区大于等于1小于等于count个字节数据,即只要有数据Read方法就立刻返回。

 

  由于Read方法的阻塞性,所以我们必须防止(如串口物理断开) Read永远不返回,而导致程序卡死。方法有:

  1. 设置ReadTimeout属性为合理值,其默认值为-1,即Read永不可能因为ReadTimeout而超时返回。

  2. 先判断serialPort.BytesToRead大于0,再调用Read方法,则Read肯定会返回。

 

代码段一:

      int nStartTime = Environment.TickCount;

      while(true)

      {

           int nNowTime = Environment.TickCount;

    if(nNowTime – nStartTime > 360)   //等待360ms

    {

          Console.WriteLine(“等待360ms后超时”);

      break;

    }

    if(serialPort.BytesToRead > 35)      //用户业务数据包长度

    {

          int nLen = serialPort.Read(outBuf, 0, 35);

          DealData(outBuf, nLen);     //验证合法包,然后处理业务

      break;

    }

    //时间消耗在循环过程中,可在这加一行 Thread.Sleep(20);

  }

 

 

代码段二:

       serialPort.ReadTimeout = 1000;     //等待1000ms  初始化

     

      //接收处理函数

      try

  {

    int nLen = serialPort.Read(outBuf, 0, serialPort. BytesToRead);  //如果接收区一直没数据,时间消耗在这,等1000ms后甩TimeoutException异常

    if(nLen > 0)

        {

             DealData(outBuf, nLen);     //进全局数据队列,然后分析队列里的合法数据包

    }

  }

  catch (TimeoutException ex)

  {

    Console.WriteLine("通信超时");

  }

你可能感兴趣的:(通信)