Winform中使用Reactivex代替BeginInvoke/Invoke来更新UI数据

时间:2023-01-23 04:25:41

首先通过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 }

Winform中使用Reactivex代替BeginInvoke/Invoke来更新UI数据