prattom
prattom

Reputation: 1753

thread sleep blocking serial port data event handler

I am reading data through serial port which is working correctly. Following is my code in short

public Form1()
{
    InitializeComponent();

    //Background worker
    m_oWorker = new BackgroundWorker();
    m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
    m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
    m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
    m_oWorker.WorkerReportsProgress = true;
    m_oWorker.WorkerSupportsCancellation = true;


    connectComPort.DataReceived += new SerialDataReceivedEventHandler(receiveData);
    enableDisable();
}

void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        backProcess();
        m_oWorker.ReportProgress(100);
    }

private void backProcess()
{
    //do some work
    Thread.Sleep(10000);
    if(check if 2000 bytes received)
    {
         //do some work
    }
}

backProcess() is running on background worker and I have a global queue in which I insert bytes received from serial port and I check this queue in if loop.

My problem is that when 2000 bytes are send from other end to pc I receive less than 1000 bytes till after thread.sleep statement but if I set a breakpoint at thread.sleep step I receive complete 2000 bytes. So does thread.sleep(background thread) blocks data receive event handler also? How can I avoid this problem?

Upvotes: 0

Views: 1676

Answers (1)

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56727

Some things don't get quite clear from your question, but I think your design is flawed.

You don't need a background worker at all and you don't need to sleep some thread.

The best way to handle serial input is to use the already asynchronous DataReceived event of the SerialPort class, which is called whenever there's data to be read (you're already doing this, as far as I can tell from your latest edit).

You can then read the existing data, append it to a StringBuilder (or fill a list of up to 2000 bytes) and launch whatever you want to do from there.

Pseudo-Code example would be:

DataReceived event
  1. Read data (using `SerialPort.ReadExisting`)
  2. Append Data to buffer, increase total number of bytes read
  3. If number of bytes >= 2000: Spawn new thread to handle the data

BackgroundWorker is NOT the right tool for this, by the way! If handling the 2000 bytes is fast enough, you don't even need to spawn a new thread at all.

Upvotes: 2

Related Questions