using System; using System.IO; using System.IO.Ports; using System.Threading; namespace OmniFeaturesTest { internal class Connection { private readonly SerialPort serialPort; private readonly Thread readingThread; private Stream readingStream; public Connection(string portNr) { this.serialPort = new SerialPort(portNr) { BaudRate = 112500, Parity = Parity.None, StopBits = StopBits.One, DataBits = 8, }; this.readingThread = new Thread(this.ConnectionBeginRead); } public Action ResponseReceived; public void Close() { try { this.readingThread?.Abort(); this.readingStream?.Close(); this.serialPort?.Close(); Console.WriteLine("serial port disconnected."); } catch (Exception e) { Console.WriteLine(e.Message); } } public void Open() { this.serialPort.Open(); if (this.serialPort.IsOpen) { this.readingStream = this.serialPort.BaseStream; this.readingThread.Start(); Console.WriteLine("serial port connected."); } else { this.Close(); } } public void Send(params byte[] command) { if (this.serialPort.IsOpen) { lock (this.serialPort) { this.serialPort.Write(command, 0, command.Length); } } } private void ConnectionBeginRead() { const int length = 128; byte[] buffer = new byte[length]; AsyncCallback asyncResultCallback = _asyncResult => { if (_asyncResult.AsyncState is Stream _readingStream) { try { var bytesReaded = _readingStream.EndRead(_asyncResult); if (bytesReaded > 0) { var data = new byte[bytesReaded]; Buffer.BlockCopy(buffer, 0, data, 0, bytesReaded); this.ResponseReceived?.Invoke(data); } } catch (Exception e) { Console.WriteLine(e.Message); } } }; while (this.readingStream.CanRead) { this.readingStream .BeginRead(buffer, 0, length, asyncResultCallback, this.readingStream) .AsyncWaitHandle .WaitOne(); } } } }