2010-02-17 133 views
5

我有一個用於評估基於事件的串行端口通信(與輪詢串行端口)的WPF測試應用程序。問題是DataReceived事件似乎根本沒有觸發。.NET SerialPort DataReceived事件未觸發

我有一個非常基本的WPF表單,包含用於用戶輸入的TextBox,用於輸出的TextBlock以及用於將輸入寫入串行端口的按鈕。

下面的代碼:

public partial class Window1 : Window 
{ 
    SerialPort port; 

    public Window1() 
    { 
     InitializeComponent(); 

     port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
     port.DataReceived += 
      new SerialDataReceivedEventHandler(port_DataReceived); 
     port.Open(); 
    } 

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     Debug.Print("receiving!"); 
     string data = port.ReadExisting(); 
     Debug.Print(data); 
     outputText.Text = data; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Debug.Print("sending: " + inputText.Text); 
     port.WriteLine(inputText.Text); 
    } 
}

現在,這裏有複雜的因素:

  1. 我的工作沒有串口筆記本電腦,所以我使用了一塊稱爲虛擬串行端口仿真器的軟件來設置COM2。過去,VSPE的表現令人讚歎,並不清楚爲什麼它只會在.NET的SerialPort類中出現故障,但我提到它以防萬一。

  2. 當我點擊表單上的按鈕發送數據時,我的超級終端窗口(連接在COM2上)顯示數據正在通過。是的,當我想測試我的表單讀取端口的能力時,我斷開超級終端。

  3. 我試圖在接線事件前打開端口。不用找了。

我已閱讀另一篇文章,其中有人有類似的問題。在這種情況下,這些信息都沒有幫助我。

編輯:

這裏的控制檯版本(從http://mark.michaelis.net/Blog/TheBasicsOfSystemIOPortsSerialPort.aspx修改):

class Program 
{ 
    static SerialPort port; 

    static void Main(string[] args) 
    { 
     port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 
     port.DataReceived += 
      new SerialDataReceivedEventHandler(port_DataReceived); 
     port.Open(); 

     string text; 
     do 
     { 
      text = Console.ReadLine(); 
      port.Write(text + "\r\n"); 
     } 
     while (text.ToLower() != "q"); 
    } 

    public static void port_DataReceived(object sender, 
     SerialDataReceivedEventArgs args) 
    { 
     string text = port.ReadExisting(); 
     Console.WriteLine("received: " + text); 
    } 
}

這將消除任何擔心,這是一個線程問題(我認爲)。這也不起作用。再次,超級終端報告通過端口發送的數據,但控制檯應用程序似乎沒有觸發DataReceived事件。

編輯#2:

我意識到,我有兩個單獨的應用程序,應同時發送和從串行端口接收,所以我決定嘗試同時運行它們...

如果我鍵入到控制檯應用程序,WPF應用程序DataReceived事件觸發,預期的線程錯誤(我知道如何處理)。

如果我輸入到WPF應用程序中,控制檯應用程序DataReceived事件觸發,並且它響應數據。

我猜這個問題是在我使用VSPE軟件的地方,它被設置爲將一個串口視爲輸入和輸出。並且通過串口類的一些奇怪的事情,串口的一個實例不能既是發送者又是接收者。無論如何,我認爲它已經解決了。

回答

0

我只能猜測,這個問題確實與虛擬串行端口仿真器程序。這並不是說該軟件存在問題:到目前爲止,VSPE對我來說工作得非常好。但是,我的代碼與我如何設置VSPE連接器之間存在一些衝突。

3

我不能肯定地說,但可能存在線程問題。我相信,WPF處理線程的方式不同,並且虛擬端口的輪詢是異步的。你是否試過用Windows Forms或控制檯應用程序來證明它可以工作?

+0

請參閱上面的控制檯版本。沒有運氣。 – Klay 2010-02-17 16:44:54

2

我使用完全相同的設置,它現在完美工作,但不得不解決許多許多問題到達那裏。

這是爲什麼我最初的聲明如下:

comControl = new SerialPort(); 

//This is important - determine your min nb of bytes at which you will fire your event, mine is 9 
comControl.ReceivedBytesThreshold = 9; 

//register the event handlers 
comControl.DataReceived += new SerialDataReceivedEventHandler(OnReceive); 
comControl.PinChanged += new SerialPinChangedEventHandler(OnPinChanged); 

我分隔開端口,關閉端口方法,因爲我經常檢查,如果COM端口已被關閉。

public bool OpenPort() 
{ 
    try 
    { 
     //must keep it open to maintain connection (CTS) 
     if (!comControl.IsOpen) 
     { 
      comControl.Open(); 
      comControl.RtsEnable = true; 
     } 
    } 
    catch (Exception e) 
    { 
     //error handling here 
    } 
} 

最後,請確認您的虛擬串口驅動程序被正確安裝,並且使用的是正確的端口,即插即用爲我的適配器是不夠的。如果你想創造一種控制的,這將允許您選擇在運行時可用的端口,下面的命令會給你可用端口:

System.IO.Ports.SerialPort.GetPortNames() 
+0

編輯完成後,我看到你已經制定了一些扭曲,但你提到「通過串口類的一些奇怪的事情,串口的一個實例不能既是發送者又是接收者」。這是不正確的。 SerialPort類既可以是發送者也可以是接收者。既然你聲明事情似乎在鍛鍊,我不會詳細說明:) – Roast 2010-02-17 20:06:44

+0

那麼它絕對聽起來像古怪不在SerialPort類,但它與虛擬串行端口軟件耦合。 – Klay 2010-02-19 13:24:53

+0

+1 - 將RTS引腳設置爲Enabled是我忘記的東西。我忘了硬件流量控制。 – 2010-05-09 16:27:17

0

從窗體運行這樣的驅動程序時,我也遇到了類似的問題,雖然沒有VSPE只是一個普通的SP。 相信這是一個STA模型問題,因爲要將它包含在足夠固定的控制檯應用程序中。

0

我也使用VSPE!它確實有效。我遇到了同樣的問題,我修復它的方式是使兩個COM端口成爲VSPE中的一對,而不是僅創建兩個虛擬COM端口

0

最近我遇到了一個類似奇怪的問題,但只限於某些機器上。正如Dave Swersky指出的那樣,這可能是一個線程問題,特別是如果你在.NET 4.0或更高版本下運行的話。

在.NET 4.0中,事件處理程序是在ThreadPool線程上觸發的,並且在某些情況下可能會在發生之前發生大量延遲。 (在我的代碼中,在.NET 2.0下完美運行,只要升級到.NET 4.5就會出現問題。事件處理程序通常會比預期更晚觸發,有時不會觸發全部!)

調用ThreadPool.SetMinThreads(...)具有更大的完成線程值使問題消失的速度達到它的速度。在我們的應用ThreadPool.SetMinThreads(2, 4)的情況下是足夠的。在哪裏觀察到這個問題時,默認值(通過調用ThreadPool.SetMinThreads作爲獲得)的機器均爲2

7
port.DtrEnable = true; 

這解決了這個問題對我來說,沒有啓用DataTransmitReady標誌,所以沒有數據被接收。

+1

這對我來說也是經過了連接到平板電腦的平衡5個小時的苦惱。一家公司的餘額(OHaus)在沒有這條線的情況下通信良好,下一家公司的餘額(賽多利斯)不是。 – jaredbaszler 2015-06-30 14:39:18

0

兩天前我有同樣的問題,這是一個很頭痛的問題,因爲我需要今天提供應用程序。所以..在太多googleashion之後,我認爲這個問題是另一回事,而不是我的代碼。

我的解決方案是卸載McAfee防病毒和所有與此相關的事情。當我看到McAfee的日誌時,它記錄了有關停止線程的記錄,並且我假定SerialDataReceivedEventHandler()在一個線程中運行。

我希望這個解決方案適合你。問候。