在线程中运行的serialPort.DataReceived不起作用

时间:2012-10-09 13:43:16

标签: c# multithreading compact-framework serial-port

我正在线程中检查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没有收到任何东西,我无法弄明白为什么。它在线程之外工作但不在线程中的事实令我感到沮丧。

我感谢任何帮助。先谢谢!

2 个答案:

答案 0 :(得分:1)

事件必须在已经声明为serialPort1的同一个线程(我猜UI线程)中运行。您可以在不同的线程中执行serialPort1_DataReceived事件中的代码。该线程应该由serialPort1_DataReceived事件处理程序启动。问题是CompactFramework没有ParameterisedThreadStart,因此您无法有效地将接收到的数据传递给线程。您需要使用委托设置一些全局字段。

答案 1 :(得分:1)

是的,但我认为你的线程在事件被触发之前完成。您应该以下列方式创建表单,请注意这是桌面代码,但模拟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");
    }
}

希望它能以这种方式运作。