9
votes

Is it safe to read and write to a serial port at the same time via different threads (one read thread and one write thread)? Would it be necessary to add locking around reading/writing in each thread?

3

3 Answers

10
votes

Reading and writing to the serial port "at the same time" from different threads is a standard way to handle serial port communications: one thread handles reading, and one handles writing. Acceptable.

There are a number of serial-based devices that send data asynchronously to the host machine while still allowing commands to be sent to the device itself: devices such as barcode scanners, tag scanners and cameras.

Problems?

Problems arise when you attempt to synchronize your communication to and from the device.

For instance, you want to write a command and then immediately read back any response. Well, in that case you would suspend the reading thread and manually read off all the serial port data after having written the command. After the command has been processed, the reading thread can start up again.

Summary

In general through, I would suggest only have one extra thread that processes all the reading of port data and fires off events, such as DataReceived and perform all your writes from your main thread.

6
votes

From the documentation of SerialPort:

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Since Read and Write are not static, they would not be threadsafe. It's a very bad idea, in any case, since the SerialPort class maintains internal buffers for you.

You'll need to synchronize your I/O to your serial port.

3
votes

I would expect the specific case you describe, with 1 Read and 1 Write thread to be safe.

The Read and Write channels on the hardware are designed to be used full duplex, and the software should be designed to support that too.
And although i could not find an explicit statement about this, the example on the MSDN Page for the SerialPort also writes from the main thread while it reads on another. Without locking.