Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该如何从串口数据触发的C#事件更新UI?_C#_Events_Callback - Fatal编程技术网

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

我应该如何从串口数据触发的C#事件更新UI?,c#,events,callback,C#,Events,Callback,我是一名技术级员工,在制造测试环境中帮助编写一些代码。具体的问题是用C#处理事件。不仅仅是点击按钮,特别是如果我有一个数据流通过串行端口来,并且必须根据通过串行端口来的数据实时更新UI。例如,如果我有两种方法最终都做相同的事情,那么它们之间的区别是什么: private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { input = (sender as SerialPort).ReadLine

我是一名技术级员工,在制造测试环境中帮助编写一些代码。具体的问题是用C#处理事件。不仅仅是点击按钮,特别是如果我有一个数据流通过串行端口来,并且必须根据通过串行端口来的数据实时更新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;
  }
   ...
}
权衡是什么?更复杂的第二种方法是一种惯例吗?在实时性能非常重要的情况下,我是否可以在任何地方都使用第一种方法?

如果我理解: 第一种方法-始终调用以更新UI 第二种方法-如果InvokeRequired返回true调用invoke else-只需执行UI操作

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

第二种方法更糟糕,因为如果未创建控件的句柄并且调用
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));
    }
}

第二个片段非常混乱。它没有任何作用。。。只需创建一个委托实例并将其分配给
d
变量,并声明一些不清楚的方法,以及一个不编译的委托。这应该在最新的编辑中修复,并记住代码中的省略号(“…”)最初是为了清晰起见而省略的其他代码的整行。我想知道的是,这两种方法之间是否有任何真正的区别(假设第二种方法在语法上是正确的,并且确实做了一些事情)。我添加了更多细节,使其在语法上更正确。请记住,为了清晰起见,我正在混淆一些东西,并且正在寻找关于这两种方法之间差异的更多一般想法。测试这一点没有任何意义。InvokeRequired,它总是正确的。所以,就这样结束吧,帮我个忙。强烈避免Invoke(),这可能会导致死锁。请改用BeginInvoke()。