old Software on a new computer

Christian little wood 1 Reputation point
2022-11-22T09:03:33.49+00:00

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?

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,821 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,199 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,031 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  
    });	  
    
    0 comments No comments

  2. 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


  3. Lex Li (Microsoft) 4,662 Reputation points Microsoft Employee
    2022-11-23T06:06:16.413+00:00

    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.