避免 C# 中的跨线程异常:安全更新 UI 控件
问题: C# 应用程序在从主 UI 线程以外的线程更新 UI 控件时经常遇到“跨线程操作无效”异常。当在单独的线程中处理来自外部源(例如微控制器的 UART 端口)的数据时,通常会发生这种情况。
场景:想象一下微控制器通过 UART 发送温度数据。 您的 C# 应用程序在后台线程中接收此数据,但尝试使用温度值直接更新 TextBox
会引发异常。
根本原因: UI 控件绑定到它们创建的线程。 从另一个线程访问它们违反了此规则。
解决方案:利用调度程序
解决这个问题的关键是使用调度程序,这是一种确保 UI 更新发生在正确线程上的机制。 这涉及一个简单但有效的模式:
创建委托:定义一个委托来封装UI更新操作:
<code class="language-csharp">delegate void SetTextCallback(string text);</code>
实现Update方法:该方法检查当前线程是否是UI线程。如果没有,它使用 Invoke
将更新编组到 UI 线程:
<code class="language-csharp">private void SetText(string text) { if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } }</code>
从后台线程更新: 在 serialPort1_DataReceived
事件处理程序(或等效)中,接收数据后调用 SetText
方法:
<code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string receivedData = serialPort1.ReadExisting(); SetText(receivedData); }</code>
这种方法可以确保所有 UI 更新都在主 UI 线程上安全地执行,从而防止跨线程异常。 InvokeRequired
检查可以有效处理更新已在正确线程上的情况,避免不必要的开销。
以上是如何在 C# 中从单独的线程安全地更新 UI 控件以避免跨线程异常?的详细内容。更多信息请关注PHP中文网其他相关文章!