如何从由串行端口数据触发的C#事件更新UI? [英] How should I update my UI from C# events triggered by serial port data?

查看:139
本文介绍了如何从由串行端口数据触发的C#事件更新UI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm a tech-level employee helping out with some of the coding in a manufacturing test environment. The specific question is handling events in C#. Not just Button_click, specifically if I have a stream of data coming through a serial port and have to update the UI in real time according to what is coming in through the serial port. For example, if I have two approaches that both ultimately do the same thing, what is the difference between:

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;
  }
   ...
}

权衡是什么?较复杂的第二种方法是否有惯例,在实时性能很重要的情况下,我可以在所有地方都使用第一种方法吗?

What are the tradeoffs? Is the more convoluted second approach a matter of convention, Could I get away with using the first approach everywhere when real-time performance is important?

推荐答案

如果我理解:
第一种方法-始终调用invoke来更新UI
第二种方法-如果InvokeRequired返回true则调用else-只是做UI东西

If i understand: First approach - always call invoke to update UI Second approach - if InvokeRequired returns true call invoke else - just do UI stuff

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

Now, if we know that handle for control was created and we want just made small and fast UI updates we can use first approach and UI will be responsible, but with Invoke deadlock is still possible. Than if we don't now if the handle for control is created we must call IsHandleCreated to ensure that Invoke will be successfull and will not throw exception. If IsHandleCreated returns false we cannot update via Invoke and we must wait for handle to be created.

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

Second approach is worse, because field.InvokeRequired may return false if handle for control is not created and when we call field.Text = d; the control's handle may be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

对我来说,这是更好的方法:

So as for me this is the better way:

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));
    }
}

这篇关于如何从由串行端口数据触发的C#事件更新UI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆