C# serial port integration with read timeouts issues

Lukas Blauzdys 0 Reputation points
2023-10-16T12:27:44.36+00:00

Hello I have a question what could be optimized for my code because for some reasons I need to increase read timeout values for serial port even tho in C++ the timeouts were even smaller and it worked fine. The C++ timeouts were 250ms and now they need to be 3000ms the code I am having troubles with is this:

 public virtual void SendSyncCommand(ISerialCommand queryCommand, ISerialCommand responseCommand)
    {
      _ = queryCommand ?? throw new ArgumentNullException(nameof(queryCommand), $"{nameof(queryCommand)} cannot be null!");
      _ = responseCommand ?? throw new ArgumentNullException(nameof(responseCommand), $"{nameof(responseCommand)} cannot be null!");

      try
      {
        bool success = false;
        int tryCount = 0;

        commandMutex.Wait();

        if(!IsConnected)
        {
          throw new DeviceException("Device is not connected");
        }

        while (!success)
        {
          tryCount++;

          string sentData = string.Empty;
          string receivedData = string.Empty;

          try
          {
            // send command
            Logger.Debug($"Request command: {queryCommand.GetType().Name} ({queryCommand.ToString()}).");
            Console.WriteLine(queryCommand.ToString());
            queryCommand.Execute(this, out sentData);

            // receive reply
            responseCommand.Receive(this, out receivedData);
            Logger.Debug($"Response command: {responseCommand.GetType().Name} ({receivedData})");

            success = true;
          }
          catch (Exception exception) when (!(exception is OperationCanceledException))
          {
            ClearBuffer();
            
            var logMessage = $"Error while communicating with the device: {exception.GetType().Name} (Sent data: [{ToHexString(sentData)}] <> Received data: [{ToHexString(receivedData)}]).";

            if (tryCount <= RetryCount) // equality to account for initial try
            {
              Logger.Warn(logMessage);
              Logger.Debug(exception.Message);
              Thread.Sleep(100); // wait before sending a new packet
            }
            else
            {
              Logger.Error(logMessage);
              Logger.Debug(exception.Message);
              throw;
            }
          }
        }
      }
      finally
      {
        commandMutex.Release();
      }
    }

 public virtual bool Read(byte[] buffer, int offset, int count)
    {
      if (count > bufferSize)
      {
        throw new ArgumentOutOfRangeException(nameof(count), $"Cannot read more than {bufferSize} bytes.");
      }

      try
      {
        connectionMutex.Wait();

        var stream = GetStream();

        if (stream is null)
        {
          return false;
        }

        if (this.offset < count)
        {
          var bytesRead = stream.Read(this.buffer, this.offset, count - this.offset);

          if (bytesRead == 0) // couldn't read any bytes, skip
          {
            throw new DeviceException("Could not read data from device connection stream.");
          }

          this.offset += bytesRead;
        }

        Array.Copy(this.buffer, 0, buffer, offset, count);

        var bytesToCopy = this.offset - count;
        Array.Copy(this.buffer, count, this.buffer, 0, bytesToCopy);
        this.offset = bytesToCopy;

        return true;
      }
      catch(Exception ex) when (ex is IOException || ex is TimeoutException || ex is InvalidOperationException)
      {
        throw new DeviceException("Failed to read data from device connection stream.", ex);
      }
      finally
      {
        connectionMutex.Release();
      }
    }
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. KOZ6.0 6,735 Reputation points
    2023-10-16T13:10:12.2066667+00:00

    SerialPort class doesn't appear in your code. :) Is this what you're talking about?

    SerialPort.ReadTimeout Property


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.