如果缓冲区为空,则如果读取,SerialPort.Read()不会返回零值 [英] SerialPort.Read() does not return a zero value if read if buffer is empty

查看:121
本文介绍了如果缓冲区为空,则如果读取,SerialPort.Read()不会返回零值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习SerialPort类,听说的一件事是使用"SerialPort.BytesToRead".非常不可靠有人告诉我,最好将SerialPort.Read()与ZERO的超时异常一起使用.我在这里得到建议:

I'm learning about the SerialPort class and one thing I've heard is that using "SerialPort.BytesToRead" is extremely unreliable. I was adviced that it's better to use SerialPort.Read() with a timeout exception of ZERO. I got that advise here:

http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport

http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport

因此,我制作了一个简单的控制台应用程序来尝试此操作:

So I made a simple console app to try this:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;

namespace SerialPortTimeout_Test
{
    class Program
    {
        static SerialPort THCPortal = new SerialPort("COM1");
        static byte[] checkForBytes = new byte[50];
        static int bytesFromBuffer = 23;

        static void Main(string[] args)
        {
            try
            {
                THCPortal.ReadTimeout = 0;
                THCPortal.Open();
                if (THCPortal.IsOpen)
                {
                    THCPortal.DiscardInBuffer();

                    /*
                    THIS NEXT LINE IS VERY INTERESTING !!!!!!!!!!
                    IT SEEMS IF THERE ARE NO BYTES TO READ THEN THIS COMMAND DOES NOT EXECUTE !!!!!!
                    I.E. I INITIALISED bytesFromBuffer TO 23 YET THE VALUE REMAINED AT 23 AFTER
                    THIS COMMAND WAS RUN.
                    SO I'D SAY THIS COMMAND ONLY COUNTS AND RETURNS THE NUMBER OF BYTES READ IF
                    THERE WERE AT LEAST ONE BYTE TO READ. IF NOT IT JUST JUMPS TO THE TIMEOUT 
                    EXCEPTION WHICH MEANS "THERE WERE NO BYTES TO READ" AND THEREFORE THE CATCH
                    BLOCK SHOULD SET bytesFromBuffer to ZERO !!!!!!!!!! 
                    */
                    bytesFromBuffer = THCPortal.Read(checkForBytes, 0, 50);

                    Console.WriteLine("Bytes read from Read Buffer = " + bytesFromBuffer);
                }
            }

            catch (TimeoutException)
            {
                Console.WriteLine("Timeout Exception - therefore there were ZERO bytes in the buffer");
                bytesFromBuffer = 0;
            }

            Console.WriteLine("Successfully moved on after catch block");
            
        }
    }
}

THCPortal.Read()应该返回一个整数值,即读取的字节数.

THCPortal.Read() should return an integer value which is the number of bytes read.

我给了变量"bytesFromBuffer".初始值为23,以便我可以在监视窗口中对其进行监视,并确认当我使用THCPortal.Read()确认读取缓冲区中没有字节时,该值将更改为零.但是价值仍然存在 在23点.

I gave the variable "bytesFromBuffer" an initial value of 23 so that I could monitor it in the watch window and confirm it would change to zero when I used THCPortal.Read() to confirm no bytes were in the read buffer. However the value remained at 23.

我只能得出结论,如果在串行读取缓冲区中没有要读取的字节,则THCPortal.Read()不会返回ANY值,甚至不会返回零.因此,"bytesFromBuffer"只是保持不变为23.

I can only conclude that if there are no bytes to read in the serial read buffer then THCPortal.Read() does not return ANY value, not even zero. Therefore "bytesFromBuffer" simply remained unchanged at 23.

在上面的代码中,我使用THCPortal.Read()作为缓冲区中零字节的确认测试.我知道在做事的方式上皱眉,以为答案"是一个例外.但众所周知,串行端口类存在严重缺陷 BytesToRead是其中之一.因此,以这种方式做事可能不会那么邪恶.

In the code above I am using THCPortal.Read() as a confirmation test for zero bytes in the buffer. I know it is a frowned on way of doing things, to catch an exception as "the answer" but it's well known that the serialport class has serious flaws and BytesToRead is one of them. So doing things this way may be a lesser evil. 

无论如何,如果读取缓冲区中没有要读取的字节,那么THCPortal.Read()不会返回任何值(甚至为零)是正确的.

Anyway would you say I'm correct about THCPortal.Read() not returning ANY value (even zero) if there are no bytes to read in the read buffer.

推荐答案

beefy23,

Hi beefy23,

据我所知,串行端口是非常慢的设备,并且read()方法会在 some 个字节可用,如果您使程序变慢,则只会得到全部23个字节,以便驱动程序有足够的时间来接收所有它们.一个简单的解决方法是继续调用Read()直到获得全部,所以尝试使用循环.

As far as I know, Serial ports are very slow devices,  and read() method returns as soon as some bytes are available, you only get all 23 of them if you make your program slow so the driver gets enough time to receive all of them. A simple fix is to keep calling Read() until you got them all, so try to use a loop.

public bool ReadData(byte[] responseBytes, int bytesExpected, int timeOut)
{
    MySerialPort.ReadTimeout = timeOut;
    int offset = 0, bytesRead;
    while(bytesExpected > 0 &&
      (bytesRead = MySerialPort.Read(responseBytes, offset, bytesExpected)) > 0)
    {
        // do some things. 
    }
    return bytesExpected == 0;
}

最诚挚的问候,

克里斯汀


这篇关于如果缓冲区为空,则如果读取,SerialPort.Read()不会返回零值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆