Search code examples
c#.netmultithreadinginvokeinvokerequired

Multi-threading, access UI control


I have a simple app with the usual UI thread and a background worker, in the background worker I need to dynamically create LinkLabels and place them in a FlowLayoutPanel. In order to do this I need to set the parent of the LinkLabel to the FlowLayoutPanel.

Here is a snippet of code I currently have, however, I get the infamous "Cross-thread operation not valid" on the line 'l.Parent = panel;'

I'm fairly new to multithreaded operations but I thought I did the invoking correctly, but obviously not. Any Suggestions?

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    FlowLayoutPanel panel = null;
    rssFeedPanel.Invoke(new MethodInvoker(delegate { panel = rssFeedPanel; }));
    l.Parent = panel;
}
else
    l.Parent = rssFeedPanel;

Solution

  • You need to actually set the Parent property on the other thread.

    LinkLabel l = new LinkLabel();
    if (rssFeedPanel.InvokeRequired) {
        rssFeedPanel.Invoke(new MethodInvoker(delegate {
            l.Parent = rssFeedPanel;
        }));
    }
    else
        l.Parent = rssFeedPanel;
    

    In general, nearly any operation involving accessing the members of a UI control can only be done from the UI thread. Some obvious exceptions are Invoke, InvokeRequired, BeginInvoke, and some of the methods of the BackgroundWorker class.

    If you wish for this case, you can also use BeginInvoke instead of Invoke.