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?

Était-ce utile?

La 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(); 
         }
     }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top