Resolved cross thread operation not valid

blinky

Member
Joined
Oct 21, 2020
Messages
7
Programming Experience
Beginner
Following from this afternoons question..... I have a class, roof, which has a public string, serialdata. Im setting the value of this by a timer which runs every 2 seconds to query the serial port. I then have a list box Im trying to populate with this data, by doing the same - creating a timer and every 2 seconds it gets the roof.serialdata variable and populates a list box. This gives me the cross-thread error - how do I work around this? I think I know what the issue is and there seem to be various articles talking about background worker but I cant figure out how to work it!

C#:
private void BtnConnect_Click(object sender, EventArgs e)
{
    string SelectedComPort = ListBoxSerialPorts.SelectedItem.ToString();
    string currentstatus = roof.OpenSerialPort(SelectedComPort);

    if (currentstatus == "Open")
    {
        btnConnect.BackColor = Color.Green;
        var timer = new System.Timers.Timer { Interval = 2000, Enabled = true };
        timer.Elapsed += OnTimedEvent;
    }
    if (currentstatus == "Port Error")
    {
        btnConnect.BackColor = Color.Red;
    }
}

private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
    ListBoxState.Items.Add(roof.serialdata);
}
 
Last edited by a moderator:

blinky

Member
Joined
Oct 21, 2020
Messages
7
Programming Experience
Beginner
Found another article that was easier to use that background worker:
C#:
if (ListBoxState.InvokeRequired)
{
    ListBoxState.Invoke(new MethodInvoker(delegate { ListBoxState.Items.Add(roof.serialdata); }));
}
 
Last edited by a moderator:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
2,393
Location
Chesapeake, VA
Programming Experience
10+
Last edited:

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,441
Location
Sydney, Australia
Programming Experience
10+
As suggested, the System.Windows.Forms.Timer is generally the one you should be using in WinForms apps. It will always raise its Tick event on the UI thread. The System.Timers.Timer will raise its Elapsed event on a thread pool thread by default but can be forced to raise it on the UI thread by assigning a control (forms are controls) to its SynchronizingObject property. The FileSystemWatcher class has a similar property.
 
Top Bottom