简体   繁体   中英

Is it right way using background worker

I want to read the messages from GSM modem in ac# application. I have written the following code and used background worker for implementing Thread.sleep() on a separate thread. But the point at which i use port.ReadExisting(), nothing is being read from the port. Am i using a wrong way of handling the background worker?

    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

Actually, if port is a SerialPort then you're doing it wrong. The SerialPort has a DataReceived event which is asynchronous and is called automatically when data comes in. This allows you to build your reply step by step and detect in your code when you've received the full reply.

You can not rely on getting the full reply just by waiting for 5 seconds.

Example:

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;
    }
}

Please note that port_DataReceived is called in a separate thread, so you need to use Invoke if you want to update the GUI.

EDIT
Just to make it clear: A BackgroundWorker should be used to perform operations in the background, report the status and/or report when it is done. Just using it to pause is not a useful thing, especially when the actual process does include some "wait until data is present" mechanism, which is the event I described above.

yes, you use the background worker in a wrong way
better would be using the direct data received events of SerialPort, or if you want to use a time based solution a one shot timer would be better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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