使用串行数据接收事件处理程序时遇到问题。数据显示在文本框上的时间有一半,而有一半时间没有。它应该是跨线程操作的问题。
这是我的Arduino代码:
int Loop = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(Loop);
Loop++;
delay(1000);
}
这是我的C#代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace arduino_test
{
public partial class Form1 : Form
{
SerialPort sPort;
public Form1()
{
InitializeComponent();
initialiseArduino();
}
public void initialiseArduino()
{
sPort = new SerialPort();
sPort.BaudRate = 9600;
sPort.PortName = "COM16";
sPort.Open();
//sPort.DataReceived += new SerialDataReceivedEventHandler(sPort_DataReceived);
}
void sPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string data = sp.ReadExisting();
displayMessage(data);
}
public void displayMessage(string data)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(displayMessage), new object[] { data });
return;
}
textBox1.Text = data;
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
string data = sPort.ReadLine();
textBox1.Text = data;
}
}
}
}
当我使用串行数据接收事件处理程序时,即使在调用之后它也会给我这个问题。
所以我尝试通过点击按钮来运行相同的线程操作,它完全正常。
有人可以告诉我我做错了什么吗?
答案 0 :(得分:3)
显而易见的差异和问题的原因是两种不同的方式。您在DataReceived事件处理程序中使用ReadExisting()
,但在Click事件处理程序中使用ReadLine()
。
ReadExisting()只是不按你希望的那样做,你只得到1或2个字符。无论“现有”是什么,自从DataReceived事件快速启动以及现代台式计算机非常快时,从未如此。然后事件再次触发,你又读了1或2个字符。你的TextBox只显示最后的内容。
改用ReadLine()。
答案 1 :(得分:0)
您可能希望使用
更新 displayMessage 方法eventtime
通过这种方式,您永远不会清除textBox1内容,并且您将获得所有值。
请考虑(取决于您的数据)您的传入数据可能包含控件字符或其他无法在文本框控件中很好地显示的内容。