2013-04-25 48 views
8

Tôi muốn đọc cổng nối tiếp nhưng chỉ khi dữ liệu đến (tôi không muốn bỏ phiếu).C# chỉ đọc Cổng nối tiếp khi dữ liệu đến

Đây là cách tôi thực hiện.

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

Và sau đó tôi bắt đầu một thread

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

và trong tôi readCom Tôi đang đọc liên tục (polling :()

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); 
     } 
    } 

Tôi muốn yout đọc khi một ngắt đang đến Nhưng làm thế nào tôi có thể làm điều đó?

Trả lời

31

Bạn sẽ phải thêm một eventHandler vào sự kiện DataReceived

Dưới đây là một ví dụ từ msdn.microsoft.com, với một số chỉnh sửa: xem ý kiến ​​:

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); 
} 

Mỗi dữ liệu đến, DataReceivedHandler sẽ kích hoạt và in dữ liệu của bạn ra cửa sổ Console. Tôi nghĩ bạn có thể làm điều này trong mã của bạn.

+1

Mã mẫu này không còn an toàn để sử dụng trong .NET 4.5. Console.ReadKey() mua lại một khóa ngăn Console.Write() viết bất cứ thứ gì. Debug.Print() là không sao. –

+0

Tôi sẽ chỉnh sửa nội dung này! Cảm ơn! –

+0

@HansPassant cảm ơn vì điều đó. Điều đó chắc chắn đã phá vỡ nhiều ví dụ về luồng trên MSDN :) – kenny

5

bạn cần đăng ký sự kiện DataReceived trước khi mở cổng, sau đó nghe sự kiện đó khi được kích hoạt.

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); 
    } 

Nối tiếp, khi có dữ liệu trong bộ đệm, sự kiện nhận dữ liệu được kích hoạt, điều này không có nghĩa là bạn có tất cả dữ liệu cùng một lúc. Bạn có thể phải đợi số lần để nhận tất cả dữ liệu của mình; đây là nơi bạn cần xử lý dữ liệu đã nhận riêng biệt, có thể giữ chúng trên bộ nhớ cache ở đâu đó, trước khi bạn thực hiện xử lý cuối cùng.

+0

Tôi biết điều này là 3 năm sau đó, nhưng tại sao ví dụ của bạn không bao gồm 'mới SerialDataReceivedEventHandler (SerialPortDataReceived);' nhưng câu trả lời trên không? Liệu nó có làm cho một sự khác biệt? –

+0

Cú pháp của tôi là từ C# 2.0 trở lên. Nó chính xác tương đương với cú pháp C# 1.0, trong đó đại biểu đóng gói phải được tạo một cách rõ ràng bằng cách sử dụng từ khóa mới. – Jegan