繁体   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