我有一个要与之交流的董事会。当我给它一些命令时,它应该返回字符串消息,并且应该发布在文本框中。我的问题是,当设备必须返回多行文本时,只有1行被发布。我也尝试过用ReadExisting代替ReadLine,但是在执行一个命令后,我只得到空字符串。
public partial class Form1 : Form
{
private string x;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.Open();
timer1.Start();
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.WriteLine(textBox1.Text);
textBox1.Clear();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(x))
{
}
else
{
textBox2.AppendText(x + "\n\r");
x = "";
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
x = serialPort1.ReadLine();
//x = serialPort1.ReadExisting();
}
private void Form1_Closing(object sender, EventArgs e)
{
serialPort1.Close();
timer1.Stop();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
答案 0 :(得分:2)
始终最好避免使用DataReceived
而只使用BaseStream
。像这样:
private async void Form1_Load(object sender, EventArgs e)
{
serialPort1.Open();
using (var reader = new StreamReader(serialPort1.BaseStream)) {
while (serialPort1.IsOpen) {
string x = await reader.ReadLineAsync();
textBox2.AppendText(x + "\r\n");
}
}
}
await
关键字以静默方式管理返回到UI线程的同步-您不需要Invoke
,不会出现跨线程故障,也不会再次调用您的事件处理程序在第一个仍在运行时被触发,则不会从访问同一变量的多个线程获得竞争条件。更容易解决问题。
作为一个样式问题,我不会将此代码直接放在您的Form Load
事件处理程序中,而是将其放在一个适当命名的辅助函数中(也许是OpenAndReadSerial()
),并从重写中调用它OnLoad()
。