我想知道为什么我在使用winform应用程序时没有接收到我的串口,但在控制台应用程序上我使用了相同的代码,它工作正常。
注意:我确实在dataReceive事件上设置了一个断点,但它没有收到任何事件。当屏幕加载时,它只接收一次,但在此之后永远不会收到事件
delegate void SetTextCallback(string text);
SerialPort serRec = null;
SerialPort ser = null;
private void SetText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.BeginInvoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
private void button1_Click(object sender, EventArgs e)
{
serRec = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One);
serRec.Open();
serRec.DataReceived += (sendexr, se) =>
{
var r = serRec.ReadLine();
SetText(r);
};
serRec.ReadTimeout = 1000;
ser = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
ser.Open();
while (true)
{
ser.WriteTimeout = 1000;
ser.WriteLine(Guid.NewGuid().ToString());
System.Threading.Thread.Sleep(3000);
}
}
答案 0 :(得分:3)
这只是猜测,但我的蜘蛛般的感觉告诉我它最有可能是UI线程问题,
SerialPort.DataReceived
事件是在一个单独的线程上引发的。如果您需要异步处理数据接收并更新UI,则需要编组回UI线程。
来自MSDN
数据时,在辅助线程上引发
DataReceived
事件 从SerialPort
对象收到。因为这个事件是在一个 辅助线程,而不是主线程,试图修改一些 主线程中的元素,如UI元素,可以引发一个 线程异常。如果有必要修改main中的元素 表单或控件,使用Invoke回发更改请求...
<强>〔实施例强>
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
var port = (SerialPort)sender;
string data = port.ReadExisting();
UpdateGui(data);
}
private void UpdateGui(string data) {
if (this.InvokeRequired) {
this.Invoke(new Action( d => UpdateGui(d) ));
return;
}
this.txtBox1.Text = data;
}
注意:这可能对控制台应用程序没有影响的原因是因为您可以在任何线程上写入控制台。
Control.InvokeRequired Property
获取一个值,该值指示调用者是否必须调用invoke方法 在对控件进行方法调用时,因为调用者在a上 与创建控件的线程不同的线程。
Control.Invoke Method (Delegate)
在拥有控件的线程上执行指定的委托 底层窗口句柄。
来自MickyD的评论
最好使用
BeginInvoke
而不是Invoke
,后者可以导致 死锁
Control.BeginInvoke Method (Delegate)
在该线程上异步执行指定的委托 控件的底层句柄是在。上创建的。