我试图通过一键点击事件打开和关闭一个串口。但是只要它碰到serialport.close部分就会挂起。为什么?
private void btn_auto_Click(object sender, EventArgs e)
{
try
{
myport = new SerialPort();
myport.BaudRate = 9600;
myport.PortName = cb_portname.Text;
myport.Open();
myport.DataReceived += new SerialDataReceivedEventHandler(myport_DataReceived2);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
}
void myport_DataReceived2(object sender, SerialDataReceivedEventArgs e)
{
try
{
in_data = myport.ReadLine();
this.Invoke(new EventHandler(displaydata_event2));
}
catch (Exception)
{
}
}
private void displaydata_event2(object sender, EventArgs e)
{
string inStr;
inStr = in_data;
if (inStr.Length == 18)
{
int indexOfSpace = inStr.IndexOf(':');
string Temp = inStr.Substring(indexOfSpace + 1);
txtData2.Text = Temp;
}
if (txtData2.Text != "")
{
myport.Close(); //===== ALWAYS HANGS AT THIS PART =====
MessageBox.Show("STOPPED");
}
}
因此,它始终挂在if txtData2不等于部分之下。 是否由于它需要一个按钮动作才能关闭一个串口,它不能自动关闭?提前致谢。
答案 0 :(得分:1)
查看SerialPort
类的源代码,特别是其关联的SerialStream
类的源代码,似乎Close()
方法将阻止等待任何引发事件的处理程序完整。
在任何情况下,您对接收到的数据的处理似乎都有点怀疑,因为如果接收的行长度恰好是18个字符,您甚至只需要查看接收到的数据,以及您正在使用实例字段在两种方法之间传递数据(非常糟糕的主意)。
但是,最有可能导致死锁的问题是,在SerialPort.Close()
事件处理程序完成之前调用DataReceived
方法。不要那样做。修复你的代码,以便处理接收的数据是一个完全独立的操作,实际上关闭串口,以便前者可以在你尝试后者之前完成。