question

Christianlittlewood-0481 avatar image
0 Votes"
Christianlittlewood-0481 asked lextm answered

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?

dotnet-csharpwindows-forms
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I wonder if you might share a small code sample to what is doing work in other threads?

0 Votes 0 ·
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

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
 });    



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Christianlittlewood-0481 avatar image
0 Votes"
Christianlittlewood-0481 answered karenpayneoregon commented

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

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

See the following in regards to BeginInvoke. Personally never had this issue but what Jon writes about BeginInvoke might just help.


0 Votes 0 ·
lextm avatar image
0 Votes"
lextm answered

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.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

thanks, that helped!

0 Votes 0 ·