Hi,
Let's say I want to have a function which reads data from the SerialPort and returns a byte[].
public byte[] RequestData(byte[] data)
{
//See code below
}
Something as simple as this really doesn't work/perform well and isn't very reliable:
byte[] response = new byte[port.ReadBufferSize];
port.Open();
port.Write(data, 0, data.Length);
Thread.Sleep(300); //Without this it doesn't even work at all
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
int count = port.Read(response, 0, port.ReadBufferSize);
Console.WriteLine("Read {0} bytes", count);
port.Close();
port.Dispose();
return response.GetSubByteArray(0, count);
I also tried replacing the Thread.Sleep with something like:
while (port.BytesToRead < 14)
{
//Maybe Thread.Sleep(10) here?
}
But that causes problems to. (PS: I know I need at least 14 bytes)
Of course a better way (I think) would be to have something like:
port.ReceivedBytesThreshold = 14;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
port.Write(data, 0, data.Length);
And then having a handler of course:
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
while (port.BytesToRead > 0)
{
//Read the data here
}
}
But then I can't return the data as the result of the function I wanted to define? The client code using this would have to subscribe to an event raised by this code, but then how would it know the response is really the response to the request it just made.
(Multiple messages might be sent, and I can imagine one message taking longer to process on the other side than the other, or something).
Any advise would be welcome
UPDATE
The following code works a lot better, but if I remove the Thread.Sleep() statements it once again stops working properly. For example, the serial port monitoring tool clearly indicates 17 bytes have been written on the serial line. The first time BytesToRead = 10 and the next time BytesToRead = 4 , but then BytesToRead remains 0 so where did the last 3 bytes go to ?
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
while (port.BytesToRead > 0)
{
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
var count = port.BytesToRead;
byte[] buffer = new byte[count];
var read = port.Read(buffer, 0, count);
if (count != read)
Console.WriteLine("Count <> Read : {0} {1}", count, read);
var collectAction = new Action(() =>
{
var response = dataCollector.Collect(buffer);
if (response != null)
{
this.OnDataReceived(response);
}
});
collectAction.BeginInvoke(null, null);
Thread.Sleep(100);
}
}