If you just want the program to quickly run as usual, follow https://stackoverflow.com/a/43890612/11182 to disable cross thread check. However, after that you need a lot of efforts to study the latest async coding best practices, such as using async/await and Tasks and getting rid of old things like BackgroundWorker.
old Software on a new computer
I have an old (build in 2008 with VS2003) application software for an industrial application based on windows forms. Now our customer wants to extend some functions, but I can't run the software properly.
I have a lot of cross-thread operations errors:
System.InvalidOperationException: "Invalid cross-thread operation: The control btn002 was accessed from a different thread than the thread it was created on."
This is not only with btn002.
I could solve those errors with using Invoke delegates,
mbtnArr[i].btn.Invoke(new MethodInvoker(delegate ()
{
}));
but some functions don't work now correctly.
Does anybody had this problem too and could it solve with an easy add of a library or something like that?
3 answers
Sort by: Newest
-
Lex Li (Microsoft) 4,742 Reputation points Microsoft Employee
2022-11-23T06:06:16.413+00:00 -
Christian little wood 1 Reputation point
2022-11-22T14:01:27.913+00:00 Hello karenpayneoregon
Thank you for your fast response. I tried this solution but it's still the same effect. When I debug step by step, it enters the control.InvokeRequired case and looses the pointer afterwards in the line:
control.Invoke(new Action(() => action(control)), null);during this procedure, the mouse hourglass is tourning with no end on the application. So it looks for me, that he just do it the first time and afterwards don't get a time window to do it again.
Christian
-
Karen Payne MVP 35,036 Reputation points
2022-11-22T12:08:56.713+00:00 See if this works for you
public static class ControlExtensions { /// <summary> /// Determines if a control needs to be invoked to prevent a cross thread violation. This is a generic /// extension method /// </summary> /// <typeparam name="T">Control</typeparam> /// <param name="control">Control</param> /// <param name="action">Predicate to run</param> /// <example> /// private void OnTimedEvent(object source, ElapsedEventArgs e) /// { /// ElapsedTimerLabel.InvokeIfRequired(label => /// { /// label.Text = $"{e.SignalTime}"; /// }); /// } /// </code> /// </example> public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : ISynchronizeInvoke { if (control.InvokeRequired) { control.Invoke(new Action(() => action(control)), null); } else { action(control); } } }
Usage where TODO is where you perform whatever action you want for
mbtnArr[i].btn
mbtnArr[i].btn.InvokeIfRequired(label => { // TODO });