using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Core.StlMes.Client.Mcp.Mch.Mcms { public delegate void ReceiveDataHandler(object sender, object data, string Message,DataType dataType); public partial class SerialPortEntity : SerialPort { private CancellationTokenSource ct = new CancellationTokenSource(); private Task task; private IProtocol _protocol; public SerialPortEntity(IProtocol iProtocol) { _protocol = iProtocol; } public void ChangeProtocol(IProtocol iProtocol) { _protocol = iProtocol; } public string StrBaudRate { get { return BaudRate.ToString(); } set { var iBaudRate = 0; if (!int.TryParse(value, out iBaudRate)) iBaudRate = 9600; BaudRate = iBaudRate; } } public string StrDataBits { get { return DataBits.ToString(); } set { var iDataBits = 0; if (!int.TryParse(value, out iDataBits)) iDataBits = 8; DataBits = iDataBits; } } public string StrParity { get { switch (Parity) { case Parity.None: return "NONE"; case Parity.Even: return "EVEN"; case Parity.Mark: return "MARK"; case Parity.Odd: return "ODD"; case Parity.Space: return "SPACE"; default: return "EVEN"; ; } } set { switch (value) { case "EVEN": Parity = Parity.Even; break; case "MARK": Parity = Parity.Mark; break; case "NONE": Parity = Parity.None; break; case "ODD": Parity = Parity.Odd; break; case "SPACE": Parity = Parity.Space; break; default: Parity = Parity.Even; break; } } } public string StrStopBits { get { switch (StopBits) { case StopBits.None: return "NONE"; case StopBits.One: return "ONE"; case StopBits.OnePointFive: return "ONEPOINTFIVE"; case StopBits.Two: return "TWO"; default: return "ONE"; ; } } set { switch (value) { case "NONE": StopBits = StopBits.None; break; case "ONE": StopBits = StopBits.One; break; case "ONEPOINTFIVE": StopBits = StopBits.OnePointFive; break; case "TWO": StopBits = StopBits.Two; break; default: StopBits = StopBits.One; break; } } } public string DeviceName { get; set; } public event ReceiveDataHandler ReceiveData; protected virtual void OnReceiveData(object data, string message, DataType dataType) { var handler = ReceiveData; if (handler != null) new Task(() => { handler(this, data, DeviceName + " " + message, dataType); }).Start(); // handler(this, data, DeviceName + " " + message); } public void Start() { try { if (_protocol == null) { OnReceiveData(null, "未指定协议", DataType.Error); return; } Open(); OnReceiveData(null, string.Format("打开串口[{0}--{1} {2} {3} {4}]成功!", PortName, StrBaudRate, StrParity, StrDataBits, StrStopBits), DataType.Open); ct = new CancellationTokenSource(); task = new Task(ReceiveTask, ct.Token); task.Start(); OnReceiveData(null, "开始监听数据",DataType.EvenMessage); } catch (Exception ex) { OnReceiveData(null, ex.Message,DataType.Error); } } public void ReceiveTask() { var ReceiveData = new List(); while (!ct.IsCancellationRequested) try { if (!IsOpen) continue; if (BytesToRead > 0) { //等待100毫秒 等足够帧过来 Thread.Sleep(100); var Datas = new byte[BytesToRead]; Read(Datas, 0, Datas.Length); ReceiveData = ReceiveData.Concat(Datas).ToList(); OnReceiveData(null, "成功接受数据:" + Datas.Select(p=>p.ToString("X2")).Aggregate((a,b)=> a+ " " + b ) + "(" + Encoding.Default.GetString(Datas.ToArray()) + ")" , DataType.ReceiveData); object Data; DeframeType Result = _protocol.AnalaysData(ReceiveData, out Data); if (Result != DeframeType.LengthLess) ReceiveData.Clear(); if (Result == DeframeType.RightFrame) { OnReceiveData(Data, "成功解析数据!" + Data.ToString(), DataType.ReceiveData); } if (Result == DeframeType.WrongFrame) { OnReceiveData(null, "数据解析失败",DataType.EvenMessage); } } } catch (Exception) { } } public void Stop() { try { ct.Cancel(); task.Wait(); } catch (Exception ex) { // ignored } Thread.Sleep(100); if (IsOpen) { Close(); OnReceiveData(null, string.Format("关闭串口[{0}]成功!", PortName),DataType.Close); } } } public enum DataType { Open =0, Close = 1, SendData= 2, ReceiveData = 3, EvenMessage= 4, Error = 5, Other = 99 } }