问题描述

当串口接收大量数据且不断更新到text等UI界面时,要是再拖动数据或者处理UI上点击功能等操作时会十分卡顿,若仅接收数据并不更新到UI时正常。
后来发现是直接使用 rx.Text = 接收到数据; 时会卡顿,参考别人使用 TextBox sender 传参就解决!

解决参考代码

卡顿代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void sp_DataReceived(object sender,SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(100); //延时100ms等待接收完数据
//this.Invoke就是跨线程访问ui的方法
this.Invoke((EventHandler)(delegate
{
if (isHex == false)
{
tbxRecvData.Text += sp.ReadLine();
}
else
{
Byte[] ReceivedData = new Byte[sp.BytesToRead]; //创建接收字符数组
sp.Read(ReceivedData, 0, ReceivedData.Length);
String RecvDataText = null;
for (int i = 0; i < ReceivedData.Length - 1; i++)
{
RecvDataText += ("0x" + ReceivedData[i].ToString("X2") + "");
}
tbxRecvData.Text += RecvDataText;
}
sp.DiscardInBuffer(); //丢弃接收缓冲区数据
}));
}

好像是这段代码哪里的问题导致界面卡死
大佬们看一下帮忙改一下

测试答案:简单编写测试,没有问题,可以正常发送接收

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;

using System.IO.Ports;

using System.Text;

using System.Windows.Forms;



namespace COMTest

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}



private SerialPort sp = new SerialPort();



private void btnOpen_Click(object sender, EventArgs e)

{

sp.PortName = "COM2";

sp.BaudRate = 9600;

sp.DataBits = 8;

sp.StopBits = StopBits.One;

sp.Parity = Parity.None;

sp.ReadTimeout = 1000;

sp.ReceivedBytesThreshold = 1;

if (!sp.IsOpen)

sp.Open();



sp.DataReceived += Sp_DataReceived;

btnOpen.Enabled = false;

}



private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

byte[] data = new byte[sp.BytesToRead];

sp.Read(data, 0, data.Length);

sp.DiscardInBuffer();

UpdateTextBox(texRev, Encoding.Default.GetString(data));

}



private void btnSend_Click(object sender, EventArgs e)

{

byte[] data = Encoding.Default.GetBytes(texData.Text);

sp.Write(data, 0, data.Length);

}

private void UpdateTextBox(TextBox sender, string content)

{

this.Invoke((EventHandler) delegate

{

sender.AppendText(content + Environment.NewLine);

});

}

}

}

例如像 RecvDataText += (“0x” + ReceivedData[i].ToString(“X2”) + “”); 这种代码,以及前边几行代码,根本不操作UI 控件,那么根本不应该放到 Invoke 中。而且只是一般地临时显示的话,使用 BeginInvoke 显然比 Invoke 更好。 你在阻塞 UI 线程(Invoke它)的时候,你执行 sp.ReadLine(); 这样的代码,这个 ReadLine 本身就是卡死、死等、阻塞式的代码,要等待对方传来换行回车或者文件结束符号才能解除阻塞。显然这样编程设计是不合适的。 尤其是通讯程序,要处理粘包、分包概念,更不应该阻塞式 Readline。


相关链接(侵删)

  1. c#串口程序界面卡死问题

=================我是分割线=================

欢迎到公众号来唠嗑: