using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.IO; using System.IO.Ports; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using BWP.WinFormControl.WeightDataFormat; namespace BWP.WinFormControl.WeightControl_ { public partial class WeightControl : UserControl { public ApplyTo ApplyTo { get; set; } //定义委托 public delegate void WeightHandle(object sender, WeightEventArgu e); //定义事件 public event WeightHandle WeightEventHandle; public WeightControl() { InitializeComponent(); weightPort = new SerialPort(); _checkComStatusThread = new Thread(SetComStatus); _checkComStatusThread.Start(); } public void Close() { if (_inQueryThread != null && _inQueryThread.IsAlive) { DisableWeight(); } if (_checkComStatusThread != null && _checkComStatusThread.IsAlive) { Thread.Sleep(10); if (_checkComStatusThread.IsAlive) { _checkComStatusThread.Abort(); } } } public WeightConfig WeightConfig { get { return WeightContext.GetConfig(ApplyTo); } } #region weightNeed SerialPort weightPort; private IDataFormat _dataFormat; private Thread _inQueryThread; private Thread _checkComStatusThread; private bool _mainProcessIsRun; readonly StringBuilder _dataStrBuilder = new StringBuilder(); readonly StringBuilder _allDataStrBuilder = new StringBuilder(); #endregion #region weightNeed void OpenSerialPort() { if (WeightConfig.RateSet == null) { throw new Exception("请先配置称相关信息"); } weightPort.PortName = WeightConfig.ComSet; weightPort.BaudRate = WeightConfig.RateSet.Value; weightPort.DataBits = WeightConfig.BitSet; weightPort.ReadBufferSize = 4096 * 100; if (!string.IsNullOrEmpty(WeightConfig.Format)) { format = "{0:{format}}".Replace("{format}", WeightConfig.Format); } switch (WeightConfig.WeightSet) { case "IND560": _dataFormat = new IND560DataFormat(); break; case "Xk3124": case "IND231": _dataFormat = new Xk3124DataFormat(); break; case "Xk3190A9": _dataFormat = new Xk3190A9DataFormat(); break; default: _dataFormat = new Xk3190D10DataFormat(); break; } if (!weightPort.IsOpen) { try { weightPort.Open(); } catch (InvalidOperationException) { MessageBox.Show(@"指定的端口已打开"); } catch (UnauthorizedAccessException) { MessageBox.Show(@"对端口的访问被拒绝"); } } } void ReadData() { _inQueryThread = new Thread(InQuery); _inQueryThread.Start(); } string format = "{0:0.00}"; private void InQuery() { while (_mainProcessIsRun) { int availableCount = weightPort.BytesToRead; if (availableCount == 0) { Thread.Sleep(1); } char[] buffer = new char[availableCount]; if (!weightPort.IsOpen) { continue; } weightPort.Read(buffer, 0, availableCount); foreach (var c in buffer) { _allDataStrBuilder.Append(c); if (c == _dataFormat.Beginchar) { _dataStrBuilder.Clear(); _dataStrBuilder.Append(c); } else if (c == _dataFormat.Endchar && _dataStrBuilder.Length == _dataFormat.DataLength - 1) { _dataStrBuilder.Append(c); bool isStatic; string str; if (_dataFormat.ParseAscii(_dataStrBuilder.ToString(), out str, out isStatic)) { if (WeightConfig.WeightType == 0) { if (string.IsNullOrEmpty(str)) str = "0"; this.Invoke(new Action(delegate () { lblChengZhong.Text = string.Format(format, decimal.Parse(str)); if (str != "0") { if (WeightEventHandle != null) { var argu = new WeightEventArgu(lblChengZhong.Text, format); WeightEventHandle(lblChengZhong, argu); } } })); } else { decimal num = 0; if (decimal.TryParse(str, out num)) { this.Invoke(new Action(delegate () { lblChengZhong.Text = string.Format(format, num); })); WeighAvgControl.Add(WeightConfig, num, isStatic); } if (WeighAvgControl.TryGetValue(out num)) { this.Invoke(new Action(delegate () { lblChengZhong.Text = string.Format(format, num); if (str != "0") { if (WeightEventHandle != null) { var argu = new WeightEventArgu(lblChengZhong.Text, format); WeightEventHandle(lblChengZhong, argu); } } })); } } } _dataStrBuilder.Clear(); } else if (_dataStrBuilder.Length != 0) { _dataStrBuilder.Append(c); } } } } private class WeighAvgControl { public static bool TryGetValue(out decimal result) { List> list; if (mWeighList.TryDequeue(out list)) { var r = list.Where(x => x.Item2).Select(x => x.Item1).GroupBy(x => x); var firstOrDefault = r.OrderByDescending(x => x.Count()).FirstOrDefault(); if (firstOrDefault != null) { result = firstOrDefault.Key; return true; } result = 0; return false; } result = 0; return false; } static ConcurrentQueue>> mWeighList = new ConcurrentQueue>>(); static List> _list = new List>(); public static void Add(WeightConfig weightConfig, decimal value, bool isStatic) { if (value >= weightConfig.MinWeight && value <= weightConfig.MaxWeight) { _list.Add(new Tuple(value, isStatic)); } else { if (_list.Count > 0) { mWeighList.Enqueue(_list); _list = new List>(); } } } } void DisableWeight() { _mainProcessIsRun = false; lblChengZhong.Text = string.Format(format, 0); format = "{0:0.00}"; if (WeightEventHandle != null) { var argu = new WeightEventArgu(lblChengZhong.Text, format); WeightEventHandle(lblChengZhong, argu); } Thread.Sleep(10); if (_inQueryThread.IsAlive) { _inQueryThread.Abort(); } if (weightPort.IsOpen) weightPort.Close(); } #endregion private void SetComStatus() { while (true) { try { var png = "stop.png"; if (_allDataStrBuilder.Length > 0) { png = "working.png"; _allDataStrBuilder.Clear(); } var imgPath = Path.Combine(Application.StartupPath, "BWP.WinFormControl.dll"); var s = Assembly.LoadFile(imgPath).GetManifestResourceStream("BWP.WinFormControl.Images." + png); if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { picNetStatus.Image = Image.FromStream(s); picNetStatus.Refresh(); })); } else { picNetStatus.Image = Image.FromStream(s); picNetStatus.Refresh(); } } catch (Exception e) { //LogUtil.Error(e.ToString()); } Thread.Sleep(500); } } private void btnWeightSet_Click(object sender, EventArgs e) { var f = new WeightSetForm(ApplyTo); if (f.ShowDialog() == DialogResult.OK) { } } private void btnStartWeight_Click(object sender, EventArgs e) { _mainProcessIsRun = true; OpenSerialPort(); ReadData(); btnStartWeight.Enabled = false; btnEndWeight.Enabled = true; } private void btnEndWeight_Click(object sender, EventArgs e) { DisableWeight(); btnStartWeight.Enabled = true; btnEndWeight.Enabled = false; } } }