0

我想在 ac# 应用程序中读取来自 GSM 调制解调器的消息。我编写了以下代码并使用后台工作人员在单独的线程上实现 Thread.sleep() 。但是在我使用 port.ReadExisting() 时,没有从端口读取任何内容。我是否使用了错误的方式来处理后台工作人员?

    private void btn_Read_Click(object sender, EventArgs e)
    {
        lvwMessages.Items.Clear();
        status_other.Visible = true;
        status_other.Text = "Loading messages...";
        if (read_all.Checked)
        {
            port.WriteLine("AT+CMGL=\"ALL\"");

        }
        else if (read_unread.Checked)
        {
            port.WriteLine("AT+CMGL=\"REC UNREAD\"");
        }
        port.DiscardOutBuffer();
        port.DiscardInBuffer();

        backgroundWorker1.RunWorkerAsync();
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(5000);
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
     string res = port.ReadExisting();// here no data is fetched into res
        //rest of the code
4

2 回答 2

2

实际上,如果port是 aSerialPort那么你做错了。有SerialPort一个DataReceived异步事件,当数据进入时会自动调用。这允许您逐步构建您的回复,并在您收到完整回复时在您的代码中检测。

不能 仅仅等待 5 秒就得到完整的答复。

例子:

private String m_receivedData = String.Empty;

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    m_receivedData += (sender as SerialPort).ReadExisting();

    if (<check whether m_receivedData contains everything I need> == true)
    {
        ProcessData(m_receivedData);
        m_receivedData = String.Empty;
    }
}

请注意,它port_DataReceived是在单独的线程中调用的,因此Invoke如果要更新 GUI,则需要使用。

编辑
只是为了说清楚: ABackgroundWorker应该用于在后台执行操作,报告状态和/或完成时报告。仅仅使用它来暂停并不是一件有用的事情,尤其是当实际过程确实包含一些“等待数据存在”机制时,这就是我上面描述的事件。

于 2012-07-20T11:10:13.197 回答
1

是的,您以错误的方式使用后台工作人员
会更好地使用 SerialPort 的直接数据接收事件,或者如果您想使用基于时间的解决方案,单次计时器会更好。

于 2012-07-20T11:09:45.633 回答