2013-04-25 79 views
8

我想讀取我的串行端口,但只有當數據來(我不想輪詢)。C#只讀串行端口數據來

這就是我的做法。

   Schnittstelle = new SerialPort("COM3"); 
       Schnittstelle.BaudRate = 115200; 
       Schnittstelle.DataBits = 8; 
       Schnittstelle.StopBits = StopBits.Two; 
      .... 

然後我啓動一個線程

   beginn = new Thread(readCom); 
      beginn.Start(); 

,並在我的readCom裏我讀連續(輪詢:()

private void readCom() 
    { 

     try 
     { 
      while (Schnittstelle.IsOpen) 
      { 

       Dispatcher.BeginInvoke(new Action(() => 
       { 

        ComWindow.txtbCom.Text = ComWindow.txtbCom.Text + Environment.NewLine + Schnittstelle.ReadExisting(); 
        ComWindow.txtbCom.ScrollToEnd(); 
       })); 

       beginn.Join(10); 

      } 
     } 
     catch (ThreadAbortException) 
     { 

     } 

     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

我想YOUT讀時中斷來臨。但我該怎麼做呢?

回答

31

你將不得不添加一個eventhandler到DataReceived事件。

下面是msdn.microsoft.com一個例子,一些編輯:看評論

public static void Main() 
{ 
    SerialPort mySerialPort = new SerialPort("COM1"); 

    mySerialPort.BaudRate = 9600; 
    mySerialPort.Parity = Parity.None; 
    mySerialPort.StopBits = StopBits.One; 
    mySerialPort.DataBits = 8; 
    mySerialPort.Handshake = Handshake.None; 

    mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 

    mySerialPort.Open(); 

    Console.WriteLine("Press any key to continue..."); 
    Console.WriteLine(); 
    Console.ReadKey(); 
    mySerialPort.Close(); 
} 

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 
    string indata = sp.ReadExisting(); 
    Debug.Print("Data Received:"); 
    Debug.Print(indata); 
} 

每當數據到來時,DataReceivedHandler將觸發您的信息打印到控制檯。我認爲你應該可以在你的代碼中做到這一點。

+1

此示例代碼在.NET 4.5中不再安全。 Console.ReadKey()獲取阻止Console.Write()寫入任何內容的鎖。 Debug.Print()沒問題。 – 2013-04-25 13:22:14

+0

我會編輯這個!謝謝! – 2013-04-25 13:23:38

+0

@HansPassant謝謝你。這肯定已經打破了MSDN上的許多線程示例:) – kenny 2013-04-25 13:23:47

5

您需要在打開端口之前訂閱DataReceived事件,然後在觸發時監聽該事件。

private void OpenSerialPort() 
    { 
     try 
     { 
      m_serialPort.DataReceived += SerialPortDataReceived; 
      m_serialPort.Open(); 
     } 
     catch (Exception ex) 
     { 
      System.Diagnostics.Debug.WriteLine(ex.Message + ex.StackTrace); 
     } 
    } 

    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     var serialPort = (SerialPort)sender; 
     var data = serialPort.ReadExisting(); 
     ProcessData(data); 
    } 

序列,當出現在緩衝區中的數據時,將觸發接收到的事件的數據,這並不意味着你馬上得到了所有數據。您可能需要等待多少次以獲取所有數據;這是您需要單獨處理接收到的數據的地方,也可以在進行最終處理之前將它們保存在某處。

+0

我知道這是3年後,但爲什麼你的例子不包括'新SerialDataReceivedEventHandler(SerialPortDataReceived);'但上面的答案呢?這有什麼不同嗎? – 2016-08-03 22:54:04

+0

我的語法來自C#2.0及以上版本。它完全等同於使用new關鍵字必須顯式創建封裝代理的C#1.0語法。 – Jegan 2016-08-04 07:44:18