Question

I have multiple serial devices connected to my PC and I am working on a program that allows users select as many as ports they want and then the program will dynamically creates TabPage and adds them to TabControl.

Each tab page will also have a multiline TextBox that will show the incoming data from the assigned serialport to it.

Here is my code that tries to create these controls dynamically:

private void AddSerialPort(string portName)
{
    ActiveSerialPorts.Add(portName);

    if (!tabControlActiveSerialPorts.Enabled)
        tabControlActiveSerialPorts.Enabled = true;

    var page = new TabPage(portName);

    page.Text = portName;

    var tb = new TextBox();
    tb.Name = portName;
    tb.Dock = DockStyle.Fill;
    tb.BackColor = Color.Black;
    tb.Multiline = true;
    page.Controls.Add(tb);
    tabControlActiveSerialPorts.TabPages.Add(page);


    var sp = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
    sp.Open();
    tb.Tag = sp;
    sp.DataReceived += delegate
                        {
                            tb.Text += sp.ReadExisting(); //LINE 87
                        };
}

PROBLEM: Here is the error I get on runtime, and break lands on line 87 (commented on code above):

Cross-thread operation not valid: Control 'COM16' accessed from a thread other than the thread it was created on.

What could be the possible pitfall here?

Was it helpful?

Solution

You're receiving data on background thread and trying to update the UI from the non-UI thread. You need to marshal the data from the background thread to the UI thread in order to update the control. This can be done using the Control.Invoke method.

sp.DataReceived += delegate 
     {
         if (tb.InvokeRequired)
         {
            tb.Invoke(new Action(() =>
            {
                tb.Text += sp.ReadExisting(); 
            }));
         }
         else
         {
            tb.Text += sp.ReadExisting(); 
         }
     }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top