C# 串口接收数据中serialPort.close()死锁

最近在做一个有关高铁模拟仓显示系统的客户端程序,在这个程序中要运用串口serialPort传输数据,因为每次接收数据结束后要更新UI界面,所以就用到了的Invoke,将更新UI的程序代码封装到一个方法中,然后通过Incoke调用,程序跑起来没有任何问题,但是当你执行serialPort.close()是程序就会发生死锁,整个程序卡在那里动都动不了。上网查了很多资料,有各种这样的说法,有的说定义一个接收数据的标志,如果在执行关闭程序是进行判断,如果数据接收完了就关闭串口,没有的话继续执行,但是经过亲自测试并没有什么卵用,最后自己研究invoke的时候发现还有Begininvoke,同时也发现了他们之间的不同,begininvoke用于后台更新UI数据无需等待的情况,而invoke用于后台更新UI数据无需要等待的情况,弄明白这两个之间的不同之后才明白原来执行serialPort.close()发生死锁的原因就是invoke在作祟,改成begininvoke就不会出现思索问题。直接上代码:

SerialPort serialPort1 = new SerialPort(configComString, 115200, Parity.None, 8, StopBits.One); //初始化串口设置
//定义委托
public delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[8];
public Displaydelegate disp_delegate;

//接收数据委托
disp_delegate = new Displaydelegate(DispUI);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);

//串口读取数据处理函数
public void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

Byte[] InputBuf = new Byte[8];

try
{
serialPort1.Read(InputBuf, 0, serialPort1.BytesToRead); //读取缓冲区的数据直到“}”即0x7D为结束符
System.Threading.Thread.Sleep(100);
this.BeginInvoke(disp_delegate, InputBuf);//disp_delegate是定义的委托事件,在委托事件中调用修改UI的程序
}
catch (TimeoutException ex) //超时处理
{
MessageBox.Show(ex.ToString());
}

}

//更新UI界面
public void DispUI(byte[] InputBuf)
{

string str = System.Text.Encoding.Default.GetString(InputBuf);
// Console.WriteLine(str);
string strW = str.Substring(0, 2);//截取str的子串,从index=0开始截取长度为2的字符串
int OutStrW = int.Parse(strW);
string strS = str.Substring(2, 2);//截取str的子串,从index=2开始截取长度为2的字符串
int OutStrS = int.Parse(strS);
OutstrWen = (OutStrW - 4).ToString();
textBox8.Text = strW;
textBox9.Text = (OutStrW - 4).ToString();
textBox10.Text = strS;
textBox11.Text = (OutStrS - 10).ToString();
}

时间: 2024-08-06 07:53:24

C# 串口接收数据中serialPort.close()死锁的相关文章

C# 解决串口接收数据不完整

方法1: 使 用缓存机制完成.首先通过定义一个成员变量List<byte> buffer = new List<byte> (4096);用来存放所有的数据,在接收函数里,通过buffer.AddRange()方法不断地将接收到的数据加入到buffer中,并同时对 buffer中的数据进行检验,如果达到一定的长度并且校验结果正确(校验方法在发送方和接收方一致),再进行处理.具体代码如下:代码 private List<byte> buffer = new List<

2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题

本文用的是VS2013MFC写串口数据接收: 第一步:首先建立一个MFC工程,成功后会跳出一个对话框,直接在对话框上点击右键->点击插入ACTIVAE控件->选择MicrosoftCommunications Control, version 6.0 成功后会显示一个电话的图标在对话框上,运行起来不会显示的 不用担心这个美观问题.如果没有这个插件的话,可能是版本太低  可以自己下载一个补上 第二步:大概的窗体搞好:   那个显示图片的大框是PICTURE控件变量 然后就要项目->类向导中

关于串口接收数据不全的问题

1 /// <summary> 2 /// 字节缓冲器 3 /// </summary> 4 public class ByteQueue 5 { 6 private List<byte> m_buffer = new List<byte>(); 7 public bool Find() 8 { 9 if (m_buffer.Count == 0) 10 return false; 11 int HeadIndex = m_buffer.FindIndex(

Qt5自带串口调试 --使用signal接收数据,自动侦测端口列表

Qt5自带串口初步用一下感觉还不错. 调试记录 .pro文件增加 QT += serialport .h文件增加 #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> private slots: void my_readuart();//串口接收数据槽函数 private: QSerialPort *my_serialport; .cpp文件 构造函数内     foreach (c

Qt串口通信接收数据不完整的解决方法(传输图片)

在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分.因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据. 本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快. //发送 [cpp] vie

Java实现RS485串口通信,发送和接收数据进行解析

最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的jar包,win64位下载地址:http://pan.baidu.com/s/1o6zLmTc):将解压后的rxtxParallel.dll和rxtxSerial.dll两个文件放在%JAVA_HOME%/jre/bin目录下,这样该包才能被正常的加载和调用. 代码如下: package com.g

delphi SPCOMM 接收数据不完整!该如何解决

SPCOMM 接收数据不完整!该如何解决 SPCOMM 接收数据不完整!我作了一个 读取地磅数据的程序,是用spcomm接收的! 总共有五台地磅,其他4台地磅数据读取都正常.但是有一台接收数据的时候,总是接收不到完整的数据,基本上小于100的数据都读不到,比如:地磅上显示1234,但是接收到的数据是12.  地磅上显示60,接收不到数据. 有时地磅上什么东西都没有,但是显示接收到 5 . 这个地磅用原来硬件供应商提供的程序可以正常工作.用我写的程序,偶尔也能正常读到数据(用程序测试了半天,有几次

STM32串口接收小结

STM32串口接收数据 稍微理一下思路,一个数据从电脑发送到STM32,然后在从STM32返回到电脑显示出来. 如上图所示,发送(1所示的路线)前,STM32的淳口需要初始化的设置.包括:波特率,字长,硬件流,停止位,奇偶校验位,模式(接收,发送,接收和发送),串口的基地址(Instance).在初始化串口的函数里面,需要调用到HAL_UART_MspInit(),这是一个虚函数(_weak),HAL_UART_MspInit()会调用到HAL_GPIO_Init(),把IO口进行配置.(模式,

stm32 串口收发数据不稳定问题

用中断接收串口数据时,有时会存在串口接收数据错乱的问题,此时需要配置的时候为 uint8 u8Data; if ( USART_GetITStatus(USART1,USART_IT_RXNE) == SET ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE);  //实际测试,先清除后存在,效果很好 u8Data=USART_ReceiveData(USART1); if (bUsart1ReFlag == 0) { g_s8RxDebugBuf