I have two objects (of the same class) which each contain a SerialPort
object. The class has a method which handles the SerialPort.DataReceived
event and is used by both SerialPort
objects.
When I instantiate each object in a separate application, each port handles its DataReceived
event individually as expected.
When I instantiate two instances of the COM_Front_End
class in the same application and send data from one serial port to the other, both port's DataReceived
event handlers fire. For short, I'll call this "cross-talk".
My class structure looks something like this:
public class COM_Front_End
{
private SerialPort_custom port;
private LockObject;
public COM_Front_End(string PortName, string BaudRate)
{
// Other code
port = new SerialPort_custom(PortName, BaudRate, new SerialDataReceivedEventHandler(SerialDataReceived));
port.Open();
}
private void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
//lock (LockObject) // A lock is not needed here. Only one SerialDataReceived event can fire at a time
//{
SerialPort port;
try
{
port = sender as SerialPort;
if (port != null)
{
byte[] buffer = new byte[port.BytesToRead];
int bytesRead = port.Read(buffer, 0, buffer.Length);
foreach (byte inByte in buffer)
{
// Byte processing code
}
}
}
catch (Exception ex)
{
// Exception handling code
}
//}
}
}
The class containing the actual SerialPort
class looks like:
public class SerialPort_custom : SerialPort
{
public SerialPort_custom(string PortName, int BaudRate, SerialDataReceivedEventHandler DataReceivedHandler)
{
this.PortName = PortName;
this.BaudRate = BaudRate;
this.Parity = System.IO.Ports.Parity.None;
this.DataBits = 8;
this.StopBits = System.IO.Ports.StopBits.One;
this.Handshake = System.IO.Ports.Handshake.None;
this.RtsEnable = true;
this.DtrEnable = true;
this.DiscardNull = false;
this.Encoding = Encoding.ASCII;
this.DataReceived += DataReceivedHandler;
}
// Other methods
}
I have two instances of the COM_Front_End
class in the same application. Whenever one instance receives data, both objects' SerialDataReceived
methods fire.
Why does the DataReceived
event handler fire for both serial ports when they are instantiated in the same application? Furthermore, how can I ensure that multiple instantiation of this class does not cause "cross-talk"?
I've found the root cause of my problem:
The project in which the
COM_Front_End
resides has two static classes. One of these classes is the Receive Buffer and the other the Transmit Buffer. Changing these classes so that they are not static solved my problem. Within eachCOM_Front_End
object is a task which polls the Receive Buffer. Since they both use the same static class, they both were pulling from this buffer which explains whyA. The
SerialDataReceived
for both objects fired.B. The data received for each was mangled/partial.
TL;DR: Non-static objects containing static objects will yield shared resources whether it is intended or not.
Please correct me wherever my explanation is faulty or incomplete.