We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

SerialPort.BytesToRead

u2envy1
u2envy1 asked
on
Medium Priority
5,619 Views
Last Modified: 2012-05-06
Im using the Serial Port.BytesToRead
If I step through the code im getting the returned data from the device.
When I run my app without breakpoints (Stepping Through) I do not get the info returned.
Is the read to slow for my Hardware. How will I know this ?
public override List<byte> ReadData()
        {            
            List<byte> bBuffer = new List<byte>();           
            byte[] data = new byte[sPort.BytesToRead];
            sPort.Read(data, 0, data.Length);
            bBuffer.AddRange(data);
 
            if (sPort.BytesToRead == 0 && sPort.IsOpen)
            {
                sPort.Close();
            }          
 
            return bBuffer;
 
        }

Open in new window

Comment
Watch Question

CERTIFIED EXPERT
Commented:
This is a common mistake when using the Stream.Read method. The Read method returns the number of bytes actually read, which may be less than the number of bytes requested. If you ignore the return value, you will not read all the data, and you will be using uninitialised data in the array.

You have to loop until you have got all the bytes that you requested, or until the Read method returns zero which means that the stream has ended.

The reason that it works when you are debugging is that you pause the code so the entire stream has already arrived when you call the Read method, so you get all the data in one call.
public override List<byte> ReadData() {
   byte[] data = new byte[sPort.BytesToRead];
   int len, pos = 0;
   while ((len = sPort.Read(data, pos, data.Length - pos)) > 0) {
      pos += len;
   }
   List<byte> result;
   if (sPort.BytesToRead == 0 && sPort.IsOpen) {
      sPort.Close();
      result = new List<byte>(data);
   } else {
      // partial result
      result = new List<byte>(pos);
      for (int i = 0; i < pos; i++) {
         result.Add(data[i]);
      }
   }
   return result;
}

Open in new window

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
Thx, That works perfect with one command send to the device.
Another issue with getting many read backs.
I have a clocking device. An employee use a card to clock in & out on the clock.
To get the punches from the clock I run a loop command to get all the punches & I put them into a List<string>
When stepping through the code I get some punches. When running the app no punches are returned.
Am I doing the loop too fast ?
CERTIFIED EXPERT
Commented:
The BytesToRead property contains the number of bytes currently in the buffer, but that might not be all the bytes that you want. If you use the BytesToRead property to determine the size of the data block, you will only get the number of bytes that has been recieved when you start to read. If you expect a data block of a certain size, you should use that as size of the array instead.

Author

Commented:
Thx, All your help is highly appreciated.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.