我正在尝试实现基于datarecieved的事件处理程序,我想我能够从端口接收数据,但是执行事件时遇到了困难..我已经尝试了ReadLine和ReadExisting ..请你评论一下我的代码..谢谢,
private void Form1_Load( object sender, EventArgs e )
{
// graphing stuff
portname = "COM1";
parity = Parity.None;
BaudRate = 115200;
stopbits = StopBits.One;
databits = 8;
port = new System.IO.Ports.SerialPort(portname);
port.Parity = parity;
port.BaudRate = BaudRate;
port.StopBits = stopbits;
port.DataBits = databits;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
count = 0;
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
line = port.ReadLine();
count++;
this.BeginInvoke(new LineReceivedEvent(LineReceived),line);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private delegate void LineReceivedEvent(string text);
private void LineReceived(string text)
{
if (zedGraphControl1.GraphPane.CurveList.Count <= 0)
return;
LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem;
if (curve == null)
return;
IPointListEdit list = curve.Points as IPointListEdit;
double value = double.Parse(text);
list.Add(count, value);
// graphing stuff
}
// graphing stuff
}
答案 0 :(得分:1)
我在串行通信方面做了很多工作,DataReceived
从未像我想要的那样工作。 SerialPort
上有一个名为ReceivedBytesThreshold
的属性应该在事件触发时发生变化,但我已经击中并错过了运气。做一些谷歌搜索这个事件,你会有成千上万的结果报告它的问题。该事件有时可以发挥作用,但我不会依赖它进行关键任务操作。
如果你正在寻找行结尾,我发现更好的方法是简单地有一个紧密的循环,如果它们可用,它会不断地将字节读入缓冲区,然后调用LineReceived
方法遇到行结束时的缓冲区。把它放在自己的线程上,应该可以解决问题。在循环中添加一些Thread.Sleep()
以防止它接管。
如果您没有寻找对串行流的瞬时反应,那么每隔一秒或半秒在线程计时器上运行它。定时器的每个tick,将所有现有字节读入缓冲区,每当遇到行结束时调用LineReceived
。
答案 1 :(得分:0)
我也在我们的某个产品中使用DataReceived事件取得了巨大成功。我正在实现的协议规定最小数据包大小为6个字节,因此我使用它是我的接收阈值。
我确保保留任何孤立的数据,并在下次发生事件时重新构建它,如果我得到不完整的读取或格式错误的数据包。我真的很少遇到这个实现的问题。我建议锁定事件处理程序,这样你就不会在串口上结束竞争,但可能不需要。