How do I resolve the semaphore timeout expired issue, with SerialPort in .NET 7 C#?

84 Views Asked by At

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.

  1. How do I best handle/recover from this issue?
  2. How do I avoid causing this issue?

What I've tried already:

  1. I've used SemaphoreSlim to limit the threads accessing this code.

  2. Attempted to open and close the serial port with delays between and after.

  3. Attempted to overwrite the SerialPort instance with a new one.

0

There are 0 best solutions below