首頁 >後端開發 >C++ >如何在 C# 中從單獨的線程安全地更新 UI 控制項以避免跨線程異常?

如何在 C# 中從單獨的線程安全地更新 UI 控制項以避免跨線程異常?

Linda Hamilton
Linda Hamilton原創
2025-01-23 02:26:10721瀏覽

How to Safely Update UI Controls from a Separate Thread in C# to Avoid Cross-Thread Exceptions?

避免 C# 中的跨執行緒異常:安全更新 UI 控制項

問題: C# 應用程式在從主 UI 執行緒以外的執行緒更新 UI 控制項時經常遇到「跨執行緒操作無效」例外。當在單獨的執行緒中處理來自外部來源(例如微控制器的 UART 連接埠)的資料時,通常會發生這種情況。

場景:想像一下微控制器透過 UART 傳送溫度資料。 您的 C# 應用程式在後台執行緒中接收此數據,但嘗試使用溫度值直接更新 TextBox 會引發異常。

根本原因: UI 控制項綁定到它們所建立的執行緒。 從另一個線程訪問它們違反了此規則。

解:利用排程程式

解決這個問題的關鍵是使用調度程序,這是一種確保 UI 更新發生在正確執行緒上的機制。 這涉及一個簡單但有效的模式:

  1. 建立委託:定義一個委託來封裝UI更新操作:

    <code class="language-csharp">delegate void SetTextCallback(string text);</code>
  2. 實作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>
  3. 從後台執行緒更新: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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn