
C# Serial Port Read All Bytes
The SerialPort class requires some “warming up” time for our users coming from VB6 or other non.NET backgrounds. One of the main reasons is that SerialPort and its underlying BaseStream are designed to behave similarly to other.NET streams, which (for example) means that Read may not act as you’d expect. And of course there are other issues that developers occasionally run into.The following are our top 5 SerialPort tips resulting from bugs we frequently we run into. Listed along with each tip is an example of a bug it applies to. We’re hoping this will help you diagnose problems in your app and save some time when working with this class.(Note: the code samples below switch between VB and C# code samples, for no other reason than those were the language the bug was written in.)Tip 1: When using SerialPort.Read(buffer, offset, count), where count is the number of bytes you want to read, check the return value, which tells you the number of bytes actually read. Examples of bugs this tip addresses. SerialPort.Read(buffer, offset, count) appears to return unexpected data.

SerialPort.Read(buffer, offset, count) does not wait for all of the bytes to be receivedDevelopers sometimes assume that count bytes/chars will be returned when Readfinishes. Consider this code sample: numBytes = myPort.Read(readBuffer, 0, readBuffer.Length)For i As Integer = 0 To readBuffer.Length - 1Console.Write(readBuffer(i) & '.' )Next iThe above code doesn’t check numBytes, the number of bytes actually read in the call to Read. So if Read returned fewer bytes than the length of readBuffer, the above loop will print out values that were in readBuffer before the call to Read.Here’s what Read actually does.
If there are bytes available on the serial port, Read returns up to count bytes but will not block for the remaining bytes. If there are no bytes available on the serial port, Read will block until at least one byte is available on the port, up until the ReadTimeout milliseconds have elapsed, at which time a TimeoutException will be thrown.To fix this in your code, check number of bytes actually read and use that value when processing the returned data. In the above code sample, you’d replace the For loop line with this: For i As Integer = 0 To numBytes - 1Tip 2.When using DataReceived event handlers, don’t assume you’ll receive an event for every byte received (assuming you’re using the default ReceivedBytesThreshold of 1). Example bug this tip addressesSudden application shutdown when interrupting a thread accessing the SerialPortWe’ve had a few bugs reporting sudden shutdown in apps – most often it’s caused by performing unsupported behavior such as interrupting a thread accessing the SerialPort.
The specific symptom in this case is an ObjectDisposedException thrown on a separate thread that cannot be caught.This behavior is related to a new managed thread exception handling policy in.NET 2.0, intended to prevent exceptions caused in background threads from being swallowed and slowly degrading application state; instead the program terminates immediately. Note that this is listed as a breaking change of.NET 2.0:We’ll address this issue more fully in a future blog post. We’ll explain why shutting down your application is actually a good thing and provide some more options of how to deal with this in your apps. The ideal way to fix this class of problems is to fix the bug that led to the exception. However, some users need a quick solution to stop their app from breaking until they can fix the bug. A quick workaround is to add the following line to your application's config file to get the earlier behavior and be able to catch the exception.
This isn’t a tip as much as an attempt to clear up some confusion we may have caused. SerialPort.ReadByte will either return a byte or throw an exception if a byte can’t be read; it never returns -1. The exceptions SerialPort can return are:. InvalidOperationException: port isn’t open. TimeoutException: timeout occurred. IOException: general IO errors; will be accompanied by specific error message.
UnauthorizedAccessException: access to port denied. EndOfStreamException: end of streamFirst, some users wonder why ReadByte doesn’t return a byte (it returns an int, and you have to cast to a byte). As background, the int return type of the underlying BaseStream matches the abstract Stream class definition of ReadByte, allowing a return value less than zero in the case that no data is available.However, SerialPort, ReadByte will never actually return -1; it will return a byte or one if the exceptions listed above.
If you’re fact checking this against our docs right now, you’ll notice an inconsistency, and we’ve just opened up a doc bug on this.Bonus Tip:Check out other recent BCL blog posts on SerialPort:. Having a problem with a simple program. When looping thru serial ports to open and read a character works fine unless a port is opened that is not sending data. Then catch(TimeoutException^ ex) or catch kicks in with a message box to tell MS about the error and app may crash.Would like the program to just 'continue', which is not accepted as an error handler.A simple answer for my simple mind without getting into polymorfism or whatever would be appreciated.
Have not found a specific answer to this on MSDN.VCExpress VS 8gp = portW-ReadByte;// or ReadCharThanks Neil.
Hi Datatree,I ran into the same problem reading data from a device. It's not a barcode scanner but still exibits the same issue. Reading most of the packets works fine but on some packets the port.BytesToRead returns 0 even though the previous DataReceivedevent read all the bytes. The packet is only 8 bytes long. The other 8 byte packets work fine. The protocol has many different length packets but I have only seen this on a few of the 8 byte packets and not all of them.
C# Serialport Class
For now I did what you did and justreturn if I see it return 0 and I know that the previous read got them all.I see the same thing. The event handler is firing twice for some reason and the second time it fires there are no bytes in the buffer to read so BytesToRead returns 0.
C# Serial Port Asynchronous Read
This makes sense of course but I don't know why the event handler is firedtwice.Thanks for you post. I'll post again if I find why this happens.Don.