using FlyADBase.Inc; using System; using System.ComponentModel; using System.IO.Ports; using System.Threading; using System.Threading.Tasks; namespace FlyADBase { public class FlyAd2021Comm_SerialPort : IFlyAd2021Comm { /// /// 串口号 /// public string Addr { get; set; } /// /// 是否异常 /// public bool IsError => !string.IsNullOrEmpty(ErrMsg); /// /// 异常信息 /// public string ErrMsg { get; private set; } /// /// Open 成功 /// public bool IsConnected { get; private set; } /// /// 运行中 /// public bool IsRunning { get; private set; } /// /// 接收task调用 /// public event Action RecMsg; public event PropertyChangedEventHandler PropertyChanged; SerialPort sp; CancellationTokenSource cancellation; CancellationTokenSource cancellation_waitforSend; public FlyAd2021Comm_SerialPort() { sp = new SerialPort(); sp.BaudRate = 115200 * 2; ; sp.Parity = Parity.None; sp.StopBits = StopBits.One; } public void SendMsg(byte[] msg) { if (!IsConnected) return; try { sp.Write(msg, 0, msg.Length); ErrMsg = null; } catch (Exception e) { ErrMsg = e.Message; IsConnected = false; } } void OnTask() { while (!cancellation.IsCancellationRequested) { ConnectTask(); if (IsConnected) { //进入接收task ReceiveTask(); } //休息一会儿,在重连 try { Task.Delay(2000, cancellation.Token).Wait(); } catch (Exception e) { //被打断了 break; } } IsConnected = false; } /// /// 连接任务 /// void ConnectTask() { sp.PortName = Addr; while (!cancellation.IsCancellationRequested) { try { sp.Open(); IsConnected = true; ErrMsg = null; return; } catch (Exception e) { //连接出错 //等待重试 ErrMsg = e.Message; } try { Task.Delay(2000, cancellation.Token).Wait(); } catch (Exception e) { //被打断 return; } } } /// /// 接收任务 /// void ReceiveTask() { sp.DataReceived += Sp_DataReceived; while (!cancellation.IsCancellationRequested) { if (!IsConnected) break; try { Task.Delay(1000, cancellation.Token).Wait(); } catch (Exception e) { //被打断了 break; } } sp.DataReceived -= Sp_DataReceived; } public void Start() { if (IsRunning) return; IsRunning = true; sp.PortName = Addr; cancellation = new CancellationTokenSource(); Task.Factory.StartNew(OnTask, cancellation.Token); } private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { int bytesToRead = sp.BytesToRead; if (bytesToRead <= 0) return; byte[] recBuf = new byte[bytesToRead]; sp.Read(recBuf, 0, bytesToRead); RecMsg?.Invoke(recBuf); } public void Stop() { if (!IsRunning) return; IsRunning = false; cancellation.Cancel(); sp.Close(); } } }