I know that when manipulating UI controls from any non-UI thread, you must marshal your calls to the UI thread to avoid issues. The general consensus is that you should use
I cannot comment yet, hopefully someone will see this and add it to the accepted answer, which otherwise is spot on.
control.Invoke(new Action(() => action(control))); should read
control.Invoke(new Action(() => action(control)), null);
As written the accepted answer will not compile because ISynchronizeInvoke.Invoke() does not have an overload with only 1 argument like Control.Invoke() does.
One other thing is that the usage might be more clear as
summary.InvokeIfRequired(c => { summary.Text = text; }); rather than as written
summary.InvokeIfRequired(c => { textBox.Text = text });