如何从串口数据触发的C#事件更新我的UI?

我是一名技术级员工,帮助制造测试环境中的一些编码.具体问题是在C#中处理事件.不仅仅是Button_click,特别是如果我有一个通过串行端口的数据流,并且必须根据通过串行端口传入的内容实时更新UI.例如,如果我有两种方法最终都做同样的事情,那么有什么区别:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    input = (sender as SerialPort).ReadLine();
    if (input.Contains("look for this"))
        this.Invoke(new EventHandler(doSomething));
}

类似的东西:

void OnGotData(object sender, EventArgs e) {...};
delegate void UpdateCallback(data d);
void doSomething(data d) {
   ...
  if (field.InvokeRequired) {
            UpdateCallback x = doSomething;
            this.Invoke(x, new object[] { d });
  }
  else {
            field.Text = d;
  }
   ...
}

有什么权衡?更复杂的第二种方法是一个常规问题吗?当实时性能很重要时,我可以在任何地方使用第一种方法吗?

如果我明白:
 第一种方法 – 始终调用invoke来更新UI
 第二种方法 – 如果InvokeRequired返回true,则调用inv – else – 只做UI内容

现在,如果我们知道控件的句柄已经创建并且我们只想进行小而快的UI更新,我们可以使用第一种方法,UI将负责,但是使用Invoke死锁仍然是可能的.如果我们现在不创建控件的句柄,我们必须调用IsHandleCreated来确保Invoke成功并且不会抛出异常.如果IsHandleCreated返回false,我们无法通过Invoke更新,我们必须等待创建句柄.

第二种方法更糟糕,因为如果没有创建控件句柄,并且当我们调用field.Text = d时,field.InvokeRequired可能返回false.可以在后台线程上创建控件的句柄,在没有消息泵的情况下隔离线程上的控件并使应用程序不稳定.

所以对我来说这是更好的方式:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    input = (sender as SerialPort).ReadLine();
    if (input.Contains("look for this"))
    {   if (this.IsHandleCreated == false)
        {
        //do some stuff to proper handle creation or just wait for handle creation
        }

        this.BeginInvoke(new EventHandler(doSomething));
    }
}
相关文章
相关标签/搜索