2013-04-25 15 views
8

Chcę odczytać mój port szeregowy, ale tylko wtedy, gdy nadchodzą dane (nie chcę odpytywać).C# tylko do odczytu Port szeregowy, gdy dane przychodzą

Tak to robię.

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

I wtedy rozpocząć wątek

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

iw moim READCOM Czytam ciągłą (odpytywanie :()

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

Chcę yout czytać, gdy nadchodzi przerwań Ale jak mogę to zrobić?

Odpowiedz

31

Będziesz musiał dodać eventHandler do zdarzenia DataReceived

Poniżej znajduje się przykład z msdn.microsoft.com, z pewnymi modyfikacjami: zobaczyć komentarze:

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

Everytime dane przychodzącej, DataReceivedHandler wyzwoli i drukuje dane do konsoli. Myślę, że powinieneś móc to zrobić w swoim kodzie.

+1

Ten przykładowy kod nie jest już bezpieczny w programie .NET 4.5. Console.ReadKey() nabywa blokadę, która uniemożliwia programowi Console.Write() zapisanie czegokolwiek. Debug.Print() jest w porządku. –

+0

Będę edytować to! Dzięki! –

+0

@HansPassant dzięki za to. To musiało zepsuć wiele przykładów wątków na MSDN :) – kenny

5

Musisz zasubskrybować zdarzenie DataReceived przed otwarciem portu, a następnie wysłuchaj tego zdarzenia po uruchomieniu.

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

Serial, gdy nie ma danych w buforze, dane otrzymane zdarzenie jest wywoływane, to nie znaczy, że masz wszystkie dane na raz. Być może będziesz musiał czekać wiele razy, aby uzyskać wszystkie swoje dane; w tym miejscu należy przetwarzać odebrane dane osobno, być może przechowywać je w pamięci podręcznej gdzieś przed wykonaniem końcowego przetwarzania.

+0

Wiem, że to 3 lata później, ale dlaczego twój przykład nie zawiera 'nowego SerialDataReceivedEventHandler (SerialPortDataReceived);' ale odpowiedź powyżej robi? Czy to robi różnicę? –

+0

Moja składnia jest z C# 2.0 i wyżej. Jest to dokładnie równoznaczne ze składnią C# 1.0, w której enkapsulujący element delegujący musi zostać jawnie utworzony za pomocą nowego słowa kluczowego. – Jegan

Powiązane problemy