簡體   English   中英

.NET SerialPort DataReceived事件未觸發

[英].NET SerialPort DataReceived event not firing

我有一個WPF測試應用程序,用於評估基於事件的串行端口通信(與輪詢串行端口)。 問題是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. 我正在處理的筆記本電腦沒有串口,因此我使用一個名為Virtual Serial Port Emulator的軟件來設置COM2。 VSPE過去曾經令人欽佩地工作,並且不清楚為什么它只會出現.NET的SerialPort類故障,但我提到它以防萬一。

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

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

這應該消除任何擔心這是一個線程問題(我認為)。 這也不起作用。 同樣,Hyperterminal報告通過端口發送的數據,但控制台應用程序似乎沒有觸發DataReceived事件。

編輯#2:

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

如果我輸入控制台應用程序,WPF應用程序DataReceived事件將觸發,並出現預期的線程錯誤(我知道如何處理)。

如果我輸入WPF應用程序,控制台應用程序DataReceived事件將觸發,並且它會回顯數據。

我猜這個問題出在我使用VSPE軟件的某個地方,該軟件設置為將一個串口視為輸入和輸出。 通過SerialPort類的一些奇怪,串行端口的一個實例不能同時是發送方和接收方。 無論如何,我認為它已經解決了。

port.DtrEnable = true;

這解決了它,我沒有啟用DataTransmitReady標志,因此沒有收到任何數據。

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

我使用完全相同的設置,它現在完美地工作,但必須解決很多問題才能到達那里。

這就是為什么我的初始聲明如下:

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

最后,驗證您的Virtual Com Port驅動程序是否已正確安裝並且您使用的是正確的端口,我的適配器的即插即用是不夠的。 如果要創建一種允許您在運行時選擇可用端口的控件,以下命令將為您提供可用端口:

System.IO.Ports.SerialPort.GetPortNames()

從Form中運行這樣的驅動程序時也有類似的問題,盡管沒有VSPE只是一個普通的SP。 相信這是一個STA模型問題,因為它將其包含在足夠固定的控制台應用程序中。

我也用VSPE! 它運行得非常好..我遇到了同樣的問題,我修復它的方法是在VSPE中使兩個COM端口成為PAIR而不是僅創建兩個虛擬COM端口

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

在.NET 4.0中,事件處理程序在ThreadPool線程上觸發,在某些情況下,在此之前可能會有很長的延遲。 (在我的代碼中,一直在.NET 2.0下完美運行,一旦我們升級到.NET 4.5就會出現問題。事件處理程序通常會比預期的更晚觸發,有時它不會被觸發所有!)

調用具有更大值的ThreadPool.SetMinThreads(...)完成線程使得問題盡快消失。 在我們的應用程序的上下文中, ThreadPool.SetMinThreads(2, 4)就足夠了。 在觀察到問題的機器上,默認值(通過調用ThreadPool.SetMinThreads獲得)都是2。

我只能推測問題確實存在於虛擬串口仿真器程序中。 這並不是說該軟件存在問題:到目前為止,VSPE對我來說效果很好。 但是我的代碼和我如何設置VSPE連接器之間存在一些沖突。

兩天前我遇到了同樣的問題,這是一個非常令人頭痛的問題,因為我今天需要提供應用程序。 所以..經過太多googleashion后我認為問題是另一回事,而不是我的代碼。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM