Reputation: 1
I am porting an existing app from Borland C++ to .NET. Application handles 4 COM Ports simultaneously, i need to synchronize them, so that whilst one port is receiving data, the other three would block until one reads all the data in the receive buffer.
Requirements are, that new version works exactly in the same way as the previous one, so i need to find a way how to synchronize those 4 ports.
P.S.
I have got 4 instances of SerialPort class.
Below is a handler for receiving data over the COM port.
private void SerialPort_DataReceived( object sender, SerialDataReceivedEventArgs e )
{
SerialPort rThis = (SerialPort)sender;
string existingData = rThis.ReadExisting();
int NumReceived = existingData.Length;
if (NumReceived > 0)
{
char[] ReceivedByte = existingData.ToCharArray();
// if RX bytes cannot be processed
if (!rThis.ProcessReceivedBytes(ReceivedByte, NumReceived))
{
rThis.ReportThreadError(ThreadId.TI_READ, 0x07FFFFF);
}
}
}
Upvotes: 0
Views: 1058
Reputation: 11607
Best thing is you have only one thread interacting with the ports, because this way you can't interact with the other ports while the thread is busy. This is exactly what you want, forget about multi-threading here.
Then, you should separate that low-level I/O thread from the GUI thread. So you'll end up with two threads that comunicate with one another over a well-defined API.
The low-level I/O thread requires a way of polling the serial ports without blocking, something like this:
while(polling) // GUI thread may interrupt polling on user request
{
foreach(SerialPort port in serialports)
{
if(port.HasDataToRead) // this is the polling you really need
{
// read data from port and handle it accordingly
}
}
// ... suspend thread now and then to prevent loop from consuming CPU time
}
The HasDataToRead
should be implemented in the event handler, meaning:
HasDataToRead
inside the SerialPort class;HasDataToRead
flag.The cycle above really is a dispatcher, while the events are only used to orchestrate the flags inside the SerialPort
instances.
Pay attention to the HasDataToRead
flag, you'll have to lock it to avoid race conditions:
lock(HasDataToRead)
{
// access HasDataToRead
}
Upvotes: 0