2013-04-25 83 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