2

在 Visual C# / .Net 应用程序中,我必须读取 SerialPort,因此我为它分配了一个 DataReceivedEventHandler。

但是,我当然不能直接从处理程序更改 UI 控件,因为它们位于单独的线程上。

解决方案似乎是使用 Control.Invoke,但是,我有太多 UI 操作要执行,所以我担心我可能没有走正确的道路。

我应该做以下哪一项?

  • 选项 A:仍然坚持使用Invoke,并使用 Invoke 对每个控件执行每个操作。

  • 选项 B:放置一个 50 毫秒的重复计时器,每 50 毫秒,我检查是否为布尔值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";    
}
4

2 回答 2

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.

于 2013-07-11T12:35:44.623 回答
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";    
}
于 2013-07-11T13:36:11.423 回答