While writing and reading to a virtual serial port in my C# ASP.NET Core 7 Web API project.
I occasionally get an IOException, when this issue occurs I seem to be unable to recover the serialport without shutting down the connected device.
Stack trace of the exception
System.IO.IOException: The semaphore timeout period has expired. : 'COM7'
at System.IO.Ports.SerialStream.EndWrite(IAsyncResult asyncResult)
at System.IO.Ports.SerialStream.Write(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
at System.IO.Ports.SerialPort.Write(Byte[] buffer, Int32 offset, Int32 count)
Instantiating of the SerialPort class
if (_serialPort == null && SerialPort.GetPortNames().Contains(poortNaam))
{
_serialPort = new SerialPort(_poortNaam, _baudrate, _parity, _dataBits, _stopBits);
_serialPort.WriteTimeout = 500;
_serialPort.ReadTimeout = 500;
_serialPort.ReadBufferSize = 8192;
_serialPort.WriteBufferSize = 8192;
_serialPort.RtsEnable = true;
Semaphore.Wait();
if (_serialPort.IsOpen)
{
_serialPort.Close();
Thread.Sleep(250);
}
_serialPort.Open();
Thread.Sleep(500);
Semaphore.Release();
}
Inside my writing method:
try
{
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
if (!_serialPort.IsOpen)
{
_serialPort.Open();
Thread.Sleep(250);
}
Trace.Write("Verstuur: ");
foreach (var item in frame)
{
Trace.Write($"{item},");
}
_serialPort.Write(frame, 0, frame.Length);
}
catch (IOException ioe)
{
Trace.WriteLine(ioe.ToString());
_serialPort.Close();
Thread.Sleep(500);
_serialPort.Open();
Thread.Sleep(500);
_serialPort.Write(frame, 0, frame.Length);
}
This is my reading method:
byte incomingByte
while(!timeout && !MessageStop)
{
try
{
int IncomingBytes = _serialPort.BytesToRead;
for (int i = 0; i < IncomingBytes ; i++)
{
incomingByte = (byte)_serialPort.ReadByte();
IncomingBytesList.Add(incomingByte );
if (incomingByte == Ex || (incomingByte == Nak && IncomingBytes == 1) || (incomingByte == Ak && IncomingBytes == 1))
{
MessageStop = true;
break;
}
}
}
catch (IOException ioe)
{
Trace.WriteLine(ioe.Message);
_serialPort.Close();
Thread.Sleep(100);
_serialPort.Open();
Thread.Sleep(200);
}
}
I assume that this issue occurs after another issue that causes the helper thread of the SerialPort class to get stuck, and triggering the timeout.
- How do I best handle/recover from this issue?
- How do I avoid causing this issue?
What I've tried already:
I've used
SemaphoreSlimto limit the threads accessing this code.Attempted to open and close the serial port with delays between and after.
Attempted to overwrite the
SerialPortinstance with a new one.