接收数据时,[serialport_datareceived]事件不止一次发生(使用虚拟串口)
when receive data, [serialport_datareceived] event occur more than once(using virtual serial port)
我正在尝试使用虚拟串行端口程序通过串行通信发送和接收数据。但是问题来了……
假设 A 是发送数据,B 是接收数据。
当A向B发送数据时,B接收数据两次(serialport_datareceived事件发生两次!)。
B每次关闭串口再打开,serialport_datareceived事件发生次数增加
我不明白为什么会这样。
A(transmit)
BaudRate = 9600
Parity = None
DataBits = 8
StopBits = 1
public transmit()
{
InitializeComponent();
foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
{
cBoxPort.Items.Add(s);
}
}
private void CBoxBaudRate_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
}
private void CBoxStopBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
}
private void CBoxDataBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
}
private void CBoxParityBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
txtReceive.AppendText("Connected\n");
btnConnect.Enabled = false;
btnClose.Enabled = true;
btnSend.Enabled = true;
}
catch (Exception ex)
{
return;
}
}
private void btnClose_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
btnClose.Enabled = false;
btnConnect.Enabled = true;
btnSend.Enabled = false;
txtReceive.AppendText("Disconnected\n");
}
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] bytesend = { 0x00 };
Debug.WriteLine("111");
serialPort1.Write(bytesend, 0, bytesend.Length);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Debug.WriteLine("444");
}
}
B(接收)
byte[] bytesend;
//Initial Conditions(SerialPort)
private void receive_Load(object sender, EventArgs e)
{
cBoxBaudRate.SelectedIndex = 0; //BaudRate = 9600
cBoxParity.SelectedIndex = 0; //Parity = None
cBoxDataBits.SelectedIndex = 0; //DataBits = 8
cBoxStopBit.SelectedIndex = 0; //StopBits = 1
cBoxPort.SelectedIndex = 1;
btnConnect.Enabled = true;
btnClose.Enabled = false;
}
//Show usable CommPort
public receive()
{
InitializeComponent();
foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
{
cBoxPort.Items.Add(s);
}
}
//Connection
private void btnConnect_Click(object sender, EventArgs e)
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
btnConnect.Enabled = false;
btnClose.Enabled = true;
}
private void btnClose_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
btnClose.Enabled = false;
btnConnect.Enabled = true;
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Debug.WriteLine("222");
}
当我调试此代码时,输出代表 111 222 222。当我按下关闭和连接按钮时,输出代表 111 222 222 222。
Every time when B close serialport and open again,
serialport_datareceived event occur increase.
是的,因为正如我所说,您应该只连接一次 DataReceived 事件。每次单击该按钮时,都会添加另一个处理程序,从而导致对单个接收进行多次触发。这与多线程无关。将连接处理程序的行从按钮单击事件向上移动到加载事件:
private void transmit_Load(object sender, EventArgs e)
{
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); // now it only gets called once
// ... other existing code ...
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
// serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); // remove this line
serialPort1.Open();
txtReceive.AppendText("Connected\n");
btnConnect.Enabled = false;
btnClose.Enabled = true;
btnSend.Enabled = true;
}
catch (Exception ex)
{
return;
}
}
您也需要在接收表单中做同样的事情。
我正在尝试使用虚拟串行端口程序通过串行通信发送和接收数据。但是问题来了…… 假设 A 是发送数据,B 是接收数据。
当A向B发送数据时,B接收数据两次(serialport_datareceived事件发生两次!)。
B每次关闭串口再打开,serialport_datareceived事件发生次数增加
我不明白为什么会这样。
A(transmit)
BaudRate = 9600
Parity = None
DataBits = 8
StopBits = 1
public transmit()
{
InitializeComponent();
foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
{
cBoxPort.Items.Add(s);
}
}
private void CBoxBaudRate_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
}
private void CBoxStopBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
}
private void CBoxDataBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
}
private void CBoxParityBits_SelectedIndexChanged(object sender, EventArgs e)
{
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
txtReceive.AppendText("Connected\n");
btnConnect.Enabled = false;
btnClose.Enabled = true;
btnSend.Enabled = true;
}
catch (Exception ex)
{
return;
}
}
private void btnClose_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
btnClose.Enabled = false;
btnConnect.Enabled = true;
btnSend.Enabled = false;
txtReceive.AppendText("Disconnected\n");
}
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] bytesend = { 0x00 };
Debug.WriteLine("111");
serialPort1.Write(bytesend, 0, bytesend.Length);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Debug.WriteLine("444");
}
}
B(接收)
byte[] bytesend;
//Initial Conditions(SerialPort)
private void receive_Load(object sender, EventArgs e)
{
cBoxBaudRate.SelectedIndex = 0; //BaudRate = 9600
cBoxParity.SelectedIndex = 0; //Parity = None
cBoxDataBits.SelectedIndex = 0; //DataBits = 8
cBoxStopBit.SelectedIndex = 0; //StopBits = 1
cBoxPort.SelectedIndex = 1;
btnConnect.Enabled = true;
btnClose.Enabled = false;
}
//Show usable CommPort
public receive()
{
InitializeComponent();
foreach (String s in System.IO.Ports.SerialPort.GetPortNames())
{
cBoxPort.Items.Add(s);
}
}
//Connection
private void btnConnect_Click(object sender, EventArgs e)
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
btnConnect.Enabled = false;
btnClose.Enabled = true;
}
private void btnClose_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
btnClose.Enabled = false;
btnConnect.Enabled = true;
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Debug.WriteLine("222");
}
当我调试此代码时,输出代表 111 222 222。当我按下关闭和连接按钮时,输出代表 111 222 222 222。
Every time when B close serialport and open again, serialport_datareceived event occur increase.
是的,因为正如我所说,您应该只连接一次 DataReceived 事件。每次单击该按钮时,都会添加另一个处理程序,从而导致对单个接收进行多次触发。这与多线程无关。将连接处理程序的行从按钮单击事件向上移动到加载事件:
private void transmit_Load(object sender, EventArgs e)
{
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); // now it only gets called once
// ... other existing code ...
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = cBoxPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudRate.Text);
serialPort1.DataBits = Convert.ToInt32(cBoxDataBits.Text);
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cBoxStopBit.Text);
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cBoxParity.Text);
// serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); // remove this line
serialPort1.Open();
txtReceive.AppendText("Connected\n");
btnConnect.Enabled = false;
btnClose.Enabled = true;
btnSend.Enabled = true;
}
catch (Exception ex)
{
return;
}
}
您也需要在接收表单中做同样的事情。