C# C-Eventhandler与表单的交叉引用

C# C-Eventhandler与表单的交叉引用,c#,forms,events,C#,Forms,Events,如果我尝试在主窗口窗体中执行此代码,则会出现以下异常: System.Windows.Forms.dll中发生类型为“System.InvalidOperationException”的未处理异常 其他信息:跨线程操作无效:控件“richTextBox1”是从创建它的线程以外的线程访问的 我发现了很多关于事件、事件处理程序和线程的信息。然而,我从未真正深入研究过事件以及如何手动创建它们或多线程。 我在MSDN上找到了这篇文章 ->Link确保只使用UI线程更新表单。每次设置UI组件的access

如果我尝试在主窗口窗体中执行此代码,则会出现以下异常:

System.Windows.Forms.dll中发生类型为“System.InvalidOperationException”的未处理异常 其他信息:跨线程操作无效:控件“richTextBox1”是从创建它的线程以外的线程访问的

我发现了很多关于事件、事件处理程序和线程的信息。然而,我从未真正深入研究过事件以及如何手动创建它们或多线程。 我在MSDN上找到了这篇文章


->Link确保只使用UI线程更新表单。每次设置UI组件的access属性(例如this.richTextBox1.AppendText)时,请注意将其委托给UI线程,以避免出现跨线程异常

你可以这样做:

delegate void UpdateDelegate(string text);

private void UpdateInformation(string text)
{
   if(this.InvokeRequired)
   {
      UpdateDelegate ud = new UpdateDelegate(UpdateInformation);
      this.BeginInvoke(ud, new object[] { text } );
   }
   else 
   {
      this.myTextBox.Text = text;
   }
}

您也可以使用匿名委托,但上面的内容可能更容易理解。

当您在

private void Arduino_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
        this.richTextBox1.AppendText(Arduino.ReadExisting());

}
该事件源自另一个线程,该线程正在监视您的Arduino

默认情况下,winforms应用程序至少有一个线程UI线程。 如果在该线程上执行代码,它将停止UI,使其无响应

因此,如果您希望在UI保持响应的同时在后台发生事情,那么这必须在单独的线程中完成

不幸的是,由于几个实际原因,线程不能使用彼此的引用

但是,他们可以互相发送消息

其中之一是调用特定操作的请求。 Windows窗体内置了两种方便的方法来利用这一点:

private void Arduino_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
        if(richTextBox1.InvokeRequired)
        {
            richTextBox1.Invoke(
               (Action)delegate 
               { 
                 richTextBox1.AppendText(Arduino.ReadExisting()); 
               }
            );
        }
}

当您知道需要调用时,为什么要检查是否需要调用?这就像在代码中编写iftrue。@Servy如果编译器/jitter意识到这一点并删除了该语句,那将是一件有趣的事情……当然,它不能。它不能知道事件总是从另一个线程触发,即使你知道。@Servy啊,当然知道了。我认为,正是这种想法让我认为,如果真的是这样的话,那么它会优化:
private void Arduino_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
        if(richTextBox1.InvokeRequired)
        {
            richTextBox1.Invoke(
               (Action)delegate 
               { 
                 richTextBox1.AppendText(Arduino.ReadExisting()); 
               }
            );
        }
}