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

C# 多視窗動態傳值:串口資料即時同步至波形視窗的正確架構

     編輯:程式設計綜合問答

問題核心

主視窗接收串口資料並解析,需即時推送至波形視窗繪圖。原嘗試在波形視窗建立 MainForm frm = new MainForm() 新實例並輪詢 tranTest(),導致取得的永遠是新實例的空資料,而非正在運行主視窗的即時資料。

正確架構:事件驅動 + 共享資料模型

  1. 定義資料模型(獨立類別,非 UI 相關)
    public class SensorData {
        public int SpeedR1 { get; set; }
        public int SpeedR2 { get; set; }
        public int SpeedSU { get; set; }
        public int SpeedAc { get; set; }
        public int Reliability { get; set; }
        public DateTime Timestamp { get; set; }
    }
  2. 主視窗發布事件
    public partial class MainForm : Form {
        public event EventHandler<SensorData> DataReceived;
        private void OnDataReceived(SensorData d) => DataReceived?.Invoke(this, d);
    
        private void serialPort1_DataReceived(...) {
            // 解析邏輯...
            var data = new SensorData { SpeedR1 = ..., Timestamp = DateTime.Now };
            BeginInvoke((Action)(() => OnDataReceived(data))); // 切回 UI 執行緒觸發事件
        }
    }
  3. 波形視窗訂閱事件
    public partial class WaveForm : Form {
        private readonly MainForm _main;
        public WaveForm(MainForm main) {
            InitializeComponent();
            _main = main;
            _main.DataReceived += (s, d) => {
                // 將 d 加入繪圖緩衝區,觸發 Invalidate()
                AddPoint(d);
            };
        }
    }
  4. 啟動時傳遞主視窗實例
    var wave = new WaveForm(this);
    wave.Show();
    

關鍵優勢

  • 解耦:波形視窗不依賴主視窗內部方法,僅依賴事件契約。
  • 即時性:事件驅動無輪詢延遲,資料產生即推送。
  • 執行緒安全:BeginInvoke 確保事件在 UI 執行緒觸發,波形視窗直接操作 UI 控件安全。

替代方案比較

方案優點缺點
事件驅動(推薦)解耦、即時、型別安全需理解事件模型
靜態類別/單例共享資料簡單強耦合、難測試、全域狀態風險
Timer 輪詢易理解延遲、CPU 浪費、同步問題
ObservableCollection + BindingWPF/MVVM 原生WinForms 需額外包裝

參考資源

C# 多視窗傳值經典教學:新浪部落格範例

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved