在Visual C#/ .Net应用程序中,我必须读取SerialPort,因此我为它分配了一个DataReceivedEventHandler。
但是,我当然不能直接从处理程序中更改UI控件,因为它们位于一个单独的线程上。
解决方案似乎是使用Control.Invoke,但是,我有太多的UI动作要执行,所以我担心我可能没有采取正确的路径。
我应该做以下哪项?
选项A:坚持使用调用,并使用Invoke为每个控件执行每个操作的每个操作。
选项B:放置一个50ms的重复计时器,每50ms,我检查一下布尔 DataReceived == true ,如果是,则相应地更新UI控件。 (每次读取串行端口DataReceivedEventHandler中的数据时,DataReceived都设置为true,否则为false。)
选项C:还有其他选择吗?
更新
以下成功(基于@ tcarvin的答案和@Hans Passant的评论)。
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
if (this.InvokeRequired())
{
this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), new object[] { sender, e });
return;
}
tbSerialStatus.Text = "Received text";
}
答案 0 :(得分:4)
我认为你在想这个。假设您在表单中编码,这样的事情应该有效。这是嘻嘻哈哈,你可能需要稍微调整一下:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), sender, e);
return;
}
// everything here runs on the UI thread, do what you like,
// and update as many UI controls as you like.
}
正如您所看到的,您不必将每个控件访问权限包含在单独的Control.Invoke
中。
答案 1 :(得分:0)
解决。这种方法有效:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
if (this.InvokeRequired())
{
this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(DataReceivedHandler), new object[] { sender, e });
return;
}
tbSerialStatus.Text = "Received text";
}