1:工具箱中拖SerialPort到主界面 2:設置好相關串口的配置(串口的接收事件爲OnDataReceived) 3:代碼以下:html
public Form1() { InitializeComponent(); foreach (var p in SerialPort.GetPortNames()) //獲取電腦上全部的串口 { cbPorts.Items.Add(p); } cbPorts.SelectedIndex = 0; } private void button2_Click(object sender, EventArgs e) { sport.PortName = cbPorts.SelectedItem.ToString(); //將要使用的串口 sport.Open(); } private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { lblID.Text = sport.BaseStream.ReadByte().ToString(); } private static int i = 0; private void timer1_Tick(object sender, EventArgs e) { if(sport.IsOpen) { sport.Write(i.ToString()); i++; } }
原本的想法是用定時器1S發一次數據,串口2.3腳相連,這樣就會本身接收到數據,結果出現以下異常:工具
「System.InvalidOperationException」類型的未經處理的異常在 System.Windows.Forms.dll 中發生 其餘信息: 線程間操做無效: 從不是建立控件「lblID」的線程訪問它。
根據 https://www.cnblogs.com/BookCode/p/5583853.html 上所說:從 SerialPort 對象接收數據時,將在輔助線程上引起 DataReceived 事件。因爲此事件在輔助線程而非主線程上引起,所以嘗試修改主線程中的一些元素(如 UI 元素)時會引起線程異常。若是有必要修改主 Form 或 Control 中的元素,必須使用 Invoke 回發更改請求,這將在正確的線程上執行.進而要想將輔助線程中所讀到的數據顯示到主線程的Form控件上時,只有經過Invoke方法來實現:this
private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { this.Invoke(new Action(() => { Byte[] buf = new Byte[1024]; lblloraid.Text = sport.BytesToRead.ToString(); int i = sport.BaseStream.Read(buf,0,sport.BytesToRead); //.ReadByte().ToString(); lblID.Text = Encoding.ASCII.GetString(buf, 0, i); })); }
這樣雖然程序沒有問題了,但我經過兩個USB轉串口互相通訊,一個每次發26個字母,正常狀況下另外一個應該每次接收到26個,但實驗結果並非這樣的,說明程序仍是有問題。線程