簡體   English   中英

在線程中運行的serialPort.DataReceived不起作用

[英]serialPort.DataReceived running in thread not working

我正在一個線程中檢查CompactFramework的GPRS連接。

線程的想法很簡單:如果程序沒有連接,那么我運行代碼連接(這段代碼給我錯誤),但如果連接正常,那么我會在60秒內再次重新檢查,依此類推。

現在,專注於連接代碼。 以下代碼檢查它是否已連接,如果不是,則我訂閱DataReceive事件。

void initFormText()
{
    if (isThereConnect()) //true if it is connected
    {
       //enable timer to recheck if it's connected
    }
    else //it isn't connected
    {  

        serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
        if (serialPort1.IsOpen)
        {
            serialPort1.Close();
        }
        serialPort1.Open();   

        timerStep.Enabled = true;
    }    
}  

現在出現問題,在serialPort1_DataReceived中我檢查數據並設置一個由timerStep測試的變量,它會做一些步驟。

問題發生在DataReceived事件中,問題是當我在一個線程之外運行以下代碼時它工作正常,它完成所有工作並建立連接, 在線程中它不起作用。 我測試這個添加了一些MessageBox ,我意識到DataReceive中的那些永遠不會出現。

void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    byte[] data = new byte[1024];
    int n = serialPort1.Read(data, 0, data.Length);
    string rec = Encoding.GetEncoding("windows-1252").GetString(data, 0, n);

    if (string.IsNullOrEmpty(rec))
    {
        return;
    }

    if (rec.Contains("AT+CIMI") && rec.Contains("OK"))
    {
        MessageBox.Show("serialPort 1");
        currState = 1;
    }
    else if (rec.Contains("READY"))
    {
        MessageBox.Show("serialPort 11");
        currState = 1;
    }
    else if (rec.Contains("0,1") || rec.Contains("0,5"))
    {
        MessageBox.Show("serialPort 2");
        currState = 2;
    }
}

因此,由於某種原因,serialPort沒有收到任何東西,我無法弄明白為什么。 它在線程之外工作但不在線程中的事實令我感到沮喪。

我感謝任何幫助。 提前致謝!

該事件必須在您已聲明serialPort1的同一線程(我猜UI線程)中運行。 您可以在不同的線程中執行serialPort1_DataReceived事件中的代碼。 該線程應該由serialPort1_DataReceived事件處理程序啟動。 問題是CompactFramework沒有ParameterisedThreadStart,因此您無法有效地將接收到的數據傳遞給線程。 您需要使用委托設置一些全局字段。

是的,但我認為你的線程在事件被觸發之前完成。 您應該以下列方式創建表單,請注意這是桌面代碼,但模擬CompactFramework中可用的內容,因為我沒有在此安裝它。 第一個Form1是主窗體,它啟動的是Thread2。 Form2有一個按鈕和Click EventHandler正在工作,但您需要使用Application.Run()顯示您的Form2。 以下是示例代碼:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread = new Thread(new ThreadStart(ThreadMethod));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
    void ThreadMethod()
    {
            Form2 f = new Form2();
            Application.Run(f);
    }
}  

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Something");
    }
}

希望它能以這種方式工作。

暫無
暫無

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

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