I had to deal with a very old printer some weeks ago, what seems to be similar to your requirements, here is what I did.
Collect the incoming results from the port in a stringbuilder, log what you get into a file. Once you identify the "the answer is complete" indicator (in my case a given length) you can invoke a callback.
public interface IHerma300
{
void GetStatus(Action<string> callback);
}
public class Herma300 : IHerma300
{
readonly System.IO.Ports.SerialPort _port;
private Action<string> _callback;
private readonly System.Text.StringBuilder _responseFromHerma;
public const int statusResponseExpectedLength = 62;
public Herma300(string portName
, int baudRate
, System.IO.Ports.Parity parity
, int dataBits
, System.IO.Ports.StopBits stopBits
, int waitTimeMs)
{
_responseFromHerma = new StringBuilder(100);
_port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
_port.DataReceived += OnPortDataReceived;
_port.Open();
_waitTimeMs = waitTimeMs;
}
private void OnPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.IO.Ports.SerialPort port = (System.IO.Ports.SerialPort)sender;
int count = port.BytesToRead;
byte[] data = new byte[count];
port.Read(data, 0, data.Length);
var dataAsString = System.Text.Encoding.Default.GetString(data);
_responseFromHerma.Append(dataAsString);
if (_responseFromHerma.Length == statusResponseExpectedLength) CompleteAnswerReceived();
}
private void CompleteAnswerReceived()
{
_callback.Invoke(_responseFromHerma.ToString());
}
public void GetStatus(Action<string> callback)
{
_callback = callback;
_responseFromHerma.Length = 0;
string getStatusCommand = "send some command to the other side";
_port.Write(getStatusCommand);
}
}
var labelPrinter = new Herma300(params...);
labelPrinter.GetStatus(OnStatusFromPrinter);
private void OnStatusFromPrinter(string result)
{
}