111,094
社区成员




private void btnSend_Click(object sender, EventArgs e)
{
if (isOpen)//写串口数据
{
try
{
sp.WriteLine(tbxSendData.Text);
}
catch (Exception)
{
MessageBox.Show("发送数据时发生错误!", "错误提示");
return;
}
}
else
{
MessageBox.Show("串口未打开!", "错误提示");
return;
}
if (!CheckSendData())//检测要发送的数据
{
MessageBox.Show("请输入要发送的数据!", "错误提示");
return;
}
lblStatus.Text = "提示!!!!";
}
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();//丢弃接收缓冲区数据
}));
}
System.Threading.Thread.Sleep(100);
以及你写的代码注释,就能想象得到你的程序将会多么“卡顿、耗费资源”了。
一个比较好一点的通讯程序,绝不会这样去 Sleep 的。写这个语句,你在有了数据必须接收的时候,反而还去“故意阻塞100毫秒),这个自相矛盾的逻辑其实就说明了设计上“不靠谱”。你 Sleep 多长时间才能保证“缓冲区里恰好收到了消息结束符”?听天有名吧!所以你选择了一个比较长的阻塞时间。
然后你又不敢选择一个较长的时间,因为如果时间越长,程序卡得越惨。
这种自相矛盾的流程其实很可笑的,写Sleep代码其实是一种比较幼稚的代码。你应该立刻接收数据,然后判断有没有接收到消息结束符。如果没有接收到,就把接收信息保存到 List<byte> 或者 MemoryStream 之类的数据结构中就行了,等以后接受到消息结束符时才统一处理。
写Sleep语句,就说明你的程序一定不流程。而占用线程、又阻塞线程的编程习惯,如果线程稍微多一些,不但会让你的CPU标高,而且还会让物理内存不够用。