Winform中使用Reactivex代替BeginInvoke/Invoke来更新UI数据
首先通过Nuget安装包System.Reactive.
ReactiveX项目 Url: https://github.com/Reactive-Extensions/Rx.NET
1 public partial class ZSerialportForm : Form 2 { 3 private SerialPort sp; 4 private byte[] buffer = new byte[1024]; 5 // 定义ReactiveX对象 6 private IScheduler scheduler = new DispatcherScheduler(Dispatcher.CurrentDispatcher); 7 public ZSerialportForm() 8 { 9 InitializeComponent(); 10 } 11 12 private void ZSerialportForm_Load(object sender, EventArgs e) 13 { 14 cbb_serials.Items.AddRange(SerialPort.GetPortNames()); 15 if (cbb_serials.Items.Count > 0) 16 cbb_serials.SelectedIndex = 0; 17 18 btn_send.Enabled = false; 19 } 20 21 public static string GetHexStr<T>(T[] data, int len = -1, string separator = " ") 22 where T : IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T> 23 { 24 string hex = ""; 25 int upper = data.Length; 26 if (len != -1) upper = len; 27 for (int i = 0; i < upper; i++) 28 { 29 hex += data[i].ToString("x2", new NumberFormatInfo()); 30 hex += separator; 31 } 32 33 hex = hex.TrimEnd(separator.ToCharArray()); 34 return hex; 35 } 36 37 /// <summary> 38 /// 打开串口 39 /// </summary> 40 private void btn_open_Click(object sender, EventArgs e) 41 { 42 if (btn_open.Text == "打开") 43 { 44 sp = new SerialPort(cbb_serials.Text, 9600); 45 sp.ReceivedBytesThreshold = 1; 46 sp.DataReceived += OnDataReceived; 47 //sp.WriteTimeout = 50; 48 //sp.ReadTimeout = 50; 49 sp.Open(); 50 sp.DiscardInBuffer(); 51 sp.DiscardOutBuffer(); 52 btn_send.Enabled = true; 53 btn_open.Text = "关闭"; 54 } 55 else if (btn_open.Text == "关闭") 56 { 57 sp.Close(); 58 sp = null; 59 btn_send.Enabled = false; 60 btn_open.Text = "打开"; 61 } 62 } 63 64 /// <summary> 65 /// 读取串口 66 /// </summary> 67 private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) 68 { 69 if (e.EventType == SerialData.Chars) 70 { 71 int len = sp.Read(buffer, 0, sp.BytesToRead); 72 string hex = GetHexStr(buffer, len); 73 // 使用ReactiveX的方式更新UI数据 74 scheduler.Schedule(() => 75 { 76 lb_read.Items.Add(hex); 77 lb_read.SetSelected(lb_read.Items.Count - 1, true); 78 }); 79 } 80 } 81 82 /// <summary> 83 /// 发送数据 84 /// </summary> 85 private void btn_send_Click(object sender, EventArgs e) 86 { 87 string[] strs = tb_send.Text.Split(' '); 88 byte[] hexs = new byte[strs.Length]; 89 for (int i = 0; i < hexs.Length; i++) 90 { 91 hexs[i] = Byte.Parse(strs[i], NumberStyles.AllowHexSpecifier); 92 } 93 94 try 95 { 96 sp.Write(hexs, 0, hexs.Length); 97 } 98 catch (Exception exception) 99 { 100 Console.WriteLine(exception); 101 throw; 102 } 103 } 104 105 private void ZSerialportForm_FormClosed(object sender, FormClosedEventArgs e) 106 { 107 if (sp != null) 108 sp.Close(); 109 } 110 }