问题描述
当串口接收大量数据且不断更新到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);
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。
相关链接(侵删)
- c#串口程序界面卡死问题
=================我是分割线=================
欢迎到公众号来唠嗑: