I have used serial port with its original methods like BytesToRead, Read and Write before. As it is said that these are unreliable and I had a lot busy waiting I am trying to switch to its asynchronous methods.
I need to read from serial port with 2 different time outs. First timeout is between two messages (2000 ms here) and second is between 2 chars (10 ms here). Therefore I change ReadTimeout for each ReadAsync call like this:
public int Read(byte[] buffer, int offset, int count, bool isFirstChar)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
try
{
m_serialPort.ReadTimeout = isFirstChar ? 2000 : 10;
Task<int> task = m_serialPort.BaseStream.ReadAsync(buffer, offset, count);
task.Wait();
return task.Result;
} catch (AggregateException err)
{
stopWatch.Stop();
int cnt = 0;
foreach (Exception e in err.InnerExceptions)
{
if (e is TimeoutException)
{
Console.WriteLine(string.Format("Exception {0}: {1} Timeout: {2} ms", ++cnt, e.Message, stopWatch.ElapsedMilliseconds));
}
}
return -1;
}
}
Output when an AggregateException occurs and no bytes are received:
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 3584 ms
Exception 1: The operation has timed-out. Timeout: 2014 ms
Exception 1: The operation has timed-out. Timeout: 2017 ms
Exception 1: The operation has timed-out. Timeout: 2012 ms
Exception 1: The operation has timed-out. Timeout: 2011 ms
Exception 1: The operation has timed-out. Timeout: 2016 ms
Exception 1: The operation has timed-out. Timeout: 2012 ms
Exception 1: The operation has timed-out. Timeout: 2011 ms
Exception 1: The operation has timed-out. Timeout: 2013 ms
Exception 1: The operation has timed-out. Timeout: 2013 ms
My questions are now:
- Is this a proper way using ReadAsync method with .Wait()?
- Is it ok to change ReadTimeout everytime before the ReadAsync call?
- Should I use CancellationToken as parameter in ReadAsync instead, and if yes whats the best way of doing that?