繁体   English   中英

使用后台工作者是否正确

[英]Is it right way using background worker

我想从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

实际上,如果portSerialPort那么您做错了。 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,则需要使用Invoke

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

是的,您以错误的方式使用了背景工作者
最好是使用SerialPort的直接数据接收事件,或者如果您想使用基于时间的解决方案,则最好使用单发计时器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM