using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; using System.Threading; using System.Collections.Concurrent; using BWP.WinFormControl.WeightDataFormat; using System.Windows.Forms; namespace BWP.WinFormControl { public enum WeightType { IND560, Xk3124, Xk3190A9, Xk3190D10 } public partial class WeightControl : UserControl { #region weight Need private IDataFormat _dataFormat; private Thread _inQueryThread, _outQueryThread; readonly StringBuilder _dataStrBuilder = new StringBuilder(); readonly ConcurrentQueue _dataQueue = new ConcurrentQueue(); Form mainForm; #endregion bool inited = false; public void InitSerialPort(string comPort, int baudRate, int dataBits) { weightSerialPort.PortName = comPort; weightSerialPort.BaudRate = baudRate; weightSerialPort.DataBits = dataBits; weightSerialPort.ReadBufferSize = 4096 * 100; inited = true; } //public SerialPort WeightSerialPort { get { return this.weightSerialPort; } } private string _valueFormat = @"0.00"; public string ValueFormat { get { return _valueFormat; } set { _valueFormat = value; } } private WeightType _weightType = WeightType.Xk3190A9; /// /// 称类型 /// public WeightType TypeOfWeight { get { return _weightType; } set { _weightType = value; } } string format { get { if (string.IsNullOrEmpty(_valueFormat)) _valueFormat = @"0.00"; return "{0:" + _valueFormat + "}"; } } public decimal? Value { get { if (string.IsNullOrEmpty(weightLabel.Text)) return null; return decimal.Parse(string.Format(format, weightLabel.Text)); } private set { weightLabel.Text = string.Format(format, value); } } public void Clear() { Value = 0; } public CheckBox EnableCheckBox { get { return enableWeightBox; } } public WeightControl() { InitializeComponent(); } private void OpenSerialPort() { if (!inited) throw new Exception("Com口没有实例化,请先调用InitSerialPort"); // 打开串口 if (!weightSerialPort.IsOpen) { try { weightSerialPort.Open(); if (mainForm == null) mainForm = ComponentUtil.GetParentFormm(this); mainForm.FormClosed += MainFrom_FormClosed; } catch (InvalidOperationException) { MessageBox.Show(@"指定的端口已打开"); } catch (UnauthorizedAccessException) { MessageBox.Show(@"对端口的访问被拒绝"); } } } void ReadData() { _inQueryThread = new Thread(InQuery); _inQueryThread.Start(); _outQueryThread = new Thread(OutQuery); _outQueryThread.Start(); } private void InQuery() { while (enableWeightBox.Checked) { int availableCount = weightSerialPort.BytesToRead; if (availableCount == 0) { Thread.Sleep(1); } char[] buffer = new char[availableCount]; if (!weightSerialPort.IsOpen) { continue; } weightSerialPort.Read(buffer, 0, availableCount); foreach (var c in buffer) { if (c == _dataFormat.Beginchar) { _dataStrBuilder.Clear(); _dataStrBuilder.Append(c); } else if (c == _dataFormat.Endchar || _dataStrBuilder.Length > _dataFormat.Bufsize) { _dataStrBuilder.Append(c); _dataQueue.Enqueue(_dataStrBuilder.ToString()); _dataStrBuilder.Clear(); } else { _dataStrBuilder.Append(c); } } } } private void OutQuery() { while (enableWeightBox.Checked) { try { bool isStatic; string str; string subStr; if (!_dataQueue.TryDequeue(out subStr)) { Thread.Sleep(1); continue; } // 解析接受的端口数据 if (_dataFormat.ParseAscii(subStr, out str, out isStatic)) { Value = decimal.Parse(str); } } catch (Exception) { Thread.Sleep(1000); continue; } Thread.Sleep(1); } } void InitWeightType() { switch (_weightType) { case WeightType.IND560: _dataFormat = new IND560DataFormat(); break; case WeightType.Xk3124: _dataFormat = new Xk3124DataFormat(); break; case WeightType.Xk3190A9: _dataFormat = new Xk3190A9DataFormat(); break; case WeightType.Xk3190D10: _dataFormat = new Xk3190D10DataFormat(); break; default: throw new Exception("未知称类型"); } } void DisableWeight() { mainForm.FormClosed -= MainFrom_FormClosed; Thread.Sleep(10); if (weightSerialPort.IsOpen) { weightSerialPort.Close(); } if (_inQueryThread.IsAlive) { _inQueryThread.Abort(); } if (_outQueryThread.IsAlive) { _outQueryThread.Abort(); } Value = 0; } private void MainFrom_FormClosed(object sender, FormClosedEventArgs e) { if (!enableWeightBox.Checked) return; DisableWeight(); } private void enableWeightBox_CheckedChanged(object sender, EventArgs e) { if (!inited) { enableWeightBox.Checked = false; throw new Exception("Com口没有实例化,请先调用InitSerialPort"); } if (enableWeightBox.Checked) { InitWeightType(); OpenSerialPort(); ReadData(); } else DisableWeight(); } } }