首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

WinForms SerialPort DataReceived 線程更新 UI 失敗:新建 Form 實例而非調用主實例

     編輯:程式設計綜合問答

錯誤代碼

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    // ...
    PowerMainForm pf = new PowerMainForm(); // 錯誤:創建新實例
    pf.setValue(); // 修改的是新實例的控件,主窗口無變化
}

原因

  • DataReceived 在**線程池線程**觸發,非 UI 線程。
  • new PowerMainForm() 創建的是**全新窗口實例**,與運行中的主窗口無關。
  • 直接操作控件屬性跨線程非法(.NET 2.0+ 默認檢查 Control.CheckForIllegalCrossThreadCalls)。

正確模式

public partial class PowerMainForm : Form {
    // 構造器傳入串口實例或靜態引用主窗口
    public PowerMainForm() { InitializeComponent(); }

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) {
        byte[] buf = new byte[serialPort1.BytesToRead];
        serialPort1.Read(buf, 0, buf.Length);
        string data = Encoding.ASCII.GetString(buf);

        // 線程安全調用 UI
        this.Invoke((Action)(() => {
            if (data.Contains("OA")) {
                label21.Text = "aa";
                label23.Visible = true;
            }
        }));
    }
}

關鍵點

  • 使用 Control.Invoke/BeginInvoke 將委托發送到 UI 線程執行。
  • 串口對象應為主窗口成員,事件處理器內部直接 this.Invoke。|
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved