我正在尝试从串口读取字节,并将它们作为字符串写入文本框。
我的问题是代码将每个字母/字符分别写入框中,而不是一个长字符串,所以如果我收到“Hello”,它将写入“H”,然后清除框,然后“e”..等
public partial class Form1 : Form
{
static SerialPort serial;
public string line;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
inputBox.Text = "Enter some text, then press enter";
serial = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serial.Open();
serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);
}
public void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// wait for the buffer
System.Threading.Thread.Sleep(300);
byte[] bytes = new byte[serial.BytesToRead];
serial.Read(bytes, 0, bytes.Length);
line = System.Text.Encoding.UTF8.GetString(bytes);
if (line != null)
{
writeRecieved(line);
}
}
public void writeRecieved (string line)
{
if (outputBox.InvokeRequired)
{
outputBox.Invoke((MethodInvoker)delegate { outputBox.Text = line; });
}
else
{
outputBox.Text = line;
}
}
然而,在调试时,它似乎只触发这些行中的每一行,并且本地视图将变量行显示为“Hello”
编辑: 我尝试追加(outputBox.Text + = line;),但每次收到新邮件时,文本框都会填充文本。我尝试了一个outputBox.Clear();在datarecieved处理程序中,但由于某种原因它在每个字节之后执行此操作
答案 0 :(得分:2)
您的计算机能够以比9600 bps更快的速度读取数据。当它调用serial.Read
时,它会读取当时缓冲区中可用的字符数。
因此,您需要继续阅读,直到获得换行符,或者按照评论中的建议执行操作,并将文本读取附加到文本框中。
在评论中回答您的问题时,您所要求的内容是不可能的。除非发件人包含某些文本结束字符,否则接收方无法知道发送方何时完成发送所有数据。发件人可能会发送"Hello"
,然后立即跟"World"
。数据逐字逐句收到。除非发送方在每个字后发送某种终结符,否则它只是接收方的字节流。
是的,Thread.Sleep
效率低下,不应该用于此类事情。
通常,通过使发件人在每行的末尾添加换行符来处理这种事情。接收器然后可以读取字符并在新行上拆分接收的文本以得到行。
使用Sleep
也会让您陷入困境。假设发送方发送"Hello"
后跟"World"
,由于某种原因,您的线程可能会休眠4320毫秒(可能在繁忙的系统上发生)而不是300,并且您得到"HelloWo"
第一个字。糟糕。