Avoiding Cross-Thread Exceptions in C#: Safely Updating UI Controls
The Problem: C# applications often encounter "Cross-thread operation not valid" exceptions when updating UI controls from threads other than the main UI thread. This commonly happens when processing data from external sources, like a microcontroller's UART port, in a separate thread.
Scenario: Imagine a microcontroller sending temperature data via UART. Your C# application receives this data in a background thread, but attempting to directly update a TextBox
with the temperature value throws the exception.
Root Cause: UI controls are bound to the thread they're created on. Accessing them from another thread violates this rule.
The Solution: Leveraging the Dispatcher
The key to resolving this is using the dispatcher, a mechanism that ensures UI updates happen on the correct thread. This involves a simple, yet effective, pattern:
Create a Delegate: Define a delegate to encapsulate the UI update operation:
<code class="language-csharp">delegate void SetTextCallback(string text);</code>
Implement the Update Method: This method checks if the current thread is the UI thread. If not, it uses Invoke
to marshal the update to the UI thread:
<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>
Update from the Background Thread: In your serialPort1_DataReceived
event handler (or equivalent), call the SetText
method after receiving data:
<code class="language-csharp">private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string receivedData = serialPort1.ReadExisting(); SetText(receivedData); }</code>
This approach ensures that all UI updates are performed safely on the main UI thread, preventing the cross-thread exception. The InvokeRequired
check efficiently handles the situation where the update is already on the correct thread, avoiding unnecessary overhead.
The above is the detailed content of How to Safely Update UI Controls from a Separate Thread in C# to Avoid Cross-Thread Exceptions?. For more information, please follow other related articles on the PHP Chinese website!