0

My question is how do you update your ui, with data from serialport, while still updating other ui components? I have tried using a background worker, but it seems to block the ui, while the data is streaming in.

Image of form:

Main UI form

My code is:

public partial class Form1 : Form
{

    static bool _continue;
    static SerialPort _serialPort;

    BackgroundWorker dataWorker;

    string message;

    public delegate void UpdateListboxData();





    private void buttonPortConnect_Click(object sender, EventArgs e)
    {




        // Set the read/write timeouts
        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;

        _serialPort.Open();
        _continue = true;

        dataWorker = new BackgroundWorker();
        dataWorker.RunWorkerAsync();
        dataWorker.DoWork += StartDataWork;



    }


    private void StartDataWork(object sender, DoWorkEventArgs e)
    {
        Delegate del = new UpdateListboxData(DataRead);
        this.Invoke(del);
    }


    private void DataRead()
    {
        while (_continue)
        {
            try
            {
                message = _serialPort.ReadLine();

            }
            catch (TimeoutException) { }
        }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Joha6210
  • 23
  • 6
  • Use the [`SerialPort.DataReceived`](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.datareceived) event. See the example there and read the Remarks section, in relation to the threading model. Use `BeginInvoke()` when you need to update the UI, not `Invoke()`. Remove the `BackgroundWorker` (that's not the way to use it anyway) – Jimi Mar 27 '20 at 10:30

3 Answers3

0

The way to update a winforms UI is to use if (control.InvokeRequired) {...} and Invoke as shown in the example here How do I update the GUI from another thread?

0

You should not read data inside the invoke'd function. This is blocking your UI.

Either read data directly in "DoWork" and invoke the delegate only with data.

Or you might use the DataReceived event of SerialPort.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
0

you have to use Serial Port DataReceived Event and Delegate

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

                if (TextBox.InvokeRequired)
                    TextBox.Invoke(new myDelegate(updateTextBox));

        }
        public delegate void myDelegate();

        public void updateTextBox()
        {
            int iBytesToRead = serialPort1.BytesToRead;
            //Your Codes For reding From Serial Port Such as this:
            char[] ch = new char[?];
            serialPort1.Read(ch, 0, ?? ).ToString();
            //........

        }