0

I want to read the messages from GSM modem in a c# 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
Shiridish
  • 4,942
  • 5
  • 33
  • 64

2 Answers2

2

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.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • yes. this might not be an idle way of reading the port. I will try going with your suggestion. But i would like to know why in the above case port.ReadExisting() is not reading any data? – Shiridish Jul 20 '12 at 11:15
  • 1
    Maybe because data is not yet read? Or data comes so fast that `port.DiscardOutBuffer(); port.DiscardInBuffer();` discards it? Remove these two lines anyway... Be it as it may: There are situations when a `BackgroundWorker` is useful. This is **not** one of them. – Thorsten Dittmar Jul 20 '12 at 11:39
1

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.

user287107
  • 9,286
  • 1
  • 31
  • 47