2013-04-25 7 views
8

Ich möchte meine serielle Schnittstelle lesen, aber nur wenn Daten kommen (ich will nicht polling).C# nur lesen Serielle Schnittstelle, wenn Daten kommen

So mache ich es.

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

Und dann fange ich einen Thread

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

und in meinem READCOM lese ich kontinuierlich (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); 
     } 
    } 

ich yout lesen wollen, wenn ein Interrupt kommt Aber wie kann ich das tun?

Antwort

31

Sie müssen dem DataReceived-Ereignis einen eventHandler hinzufügen

Unten ist ein Beispiel von msdn.microsoft.com, mit einigen Änderungen: siehe Kommentare:

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

Jedesmal Daten kommt, löst der DataReceivedHandler und druckt Ihre Daten an die Konsole. Ich denke, du solltest das in deinem Code tun können.

+1

Dieser Beispielcode ist in .NET 4.5 nicht mehr sicher zu verwenden. Console.ReadKey() erwirbt eine Sperre, die verhindert, dass Console.Write() etwas schreibt. Debug.Print() ist in Ordnung. –

+0

Ich werde das bearbeiten! Vielen Dank! –

+0

@HansPassant danke dafür. Das muss viele der Threading-Beispiele auf MSDN gebrochen haben :) – kenny

5

Sie müssen das DataReceived-Ereignis abonnieren, bevor Sie den Port öffnen, und dann dieses Ereignis abhören, wenn es ausgelöst wird.

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

Seriell, wenn Daten im Puffer, die empfangenen Daten Ereignis ausgelöst wird, bedeutet dies nicht, dass Sie auf einmal alle Ihre Daten einsehen. Möglicherweise müssen Sie mehrere Male warten, um alle Ihre Daten zu erhalten. Hier müssen Sie die empfangenen Daten separat verarbeiten, eventuell im Cache speichern, bevor Sie die endgültige Verarbeitung durchführen.

+0

Ich weiß, dass dies 3 Jahre später ist, aber warum enthält Ihr Beispiel nicht "new SerialDataReceivedEventHandler (SerialPortDataReceived)", aber die obige Antwort funktioniert? Macht es einen Unterschied? –

+0

Meine Syntax ist von C# 2.0 und höher. Es entspricht genau der C# 1.0-Syntax, in der der einkapselnde Delegat explizit mithilfe des neuen Schlüsselworts erstellt werden muss. – Jegan

Verwandte Themen