A good architecture is the bedrock of good software. Good architecture is a result of careful understanding, analysis and thought process based on years of architectural experience. If an enterprise application is built using template architecture patterns, without a proper perspective ends up with frustrating results.

An investment in good architecture provides the business sponsors and technical developers a clear path to achieving their common goals.

Windows Forms : Cross-thread operation not valid. Doing stuff Async way.

Posted in performance, thread, c#, windows form by Amar Palsapure on Tuesday, December 13, 2011

While developing Windows Form application, everyone must have faced the problem that "My windows application doesn't response when it is performing some long running task." The reason being, in most cases we are doing all the tasks on UI thread (Thread on which UI is working). Now when this thread is doing some work in background, it doesn't redraw the windows form, hence if user perform any action during this time, it hangs (Not Responding).


Now this is a big problem if you want your UI to be responsive and user friendly. To achieve this we need to do the long running task in a separate thread (other than the UI thread). There are many ways to do this, mostly used ones are 
  • Creating new thread.
  • Using BackgroundWorker
  • Timers. 
Using any  of these, one can definitely perform the long running task on a Non-UI Thread. But this will not solve the problem (in most of the cases). Reason being if you try to change  any of the controls or windows form properties through this thread you will get an error "Cross-thread operation not valid". Because that control is created by UI thread and not by the your thread. To achieve you need to do some extra work.


Step 1: Create Extension Method


    public static class ControlExtensions
    {
        public static void Invoke(this Control control, Action action)
        {
            if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
            else action.Invoke();
        }
     }


Step 2: Adapt this new Extension Method


   Now to change properties of control, you will need to do something like this
        controlName.Invoke(() => { controlName.Property = newValue; });


Now what we have done here is we have changed the property by Invoking a Windows Form delegate. In other words now when ever you call Invoke method on any control, internally the thread who has created the control will get the call with the parameters and it will execute the command given. Thus the thread who has created the control is itself handling the calls made to the control. Doing so the problem "Cross-thread operation not valid" can be circumvent.


Finally small code snippet to demonstrate the usage. In this snippet I am doing some long running task on button click (btnGo is the button control) and once the task is over I am changing the button text to "Done":


    Windows Form Code Behind


         private void btnGo_Click(object sender, EventArgs e)
         {
                Thread thread = new Thread(new ThreadStart(DoWorkAsync));
                 thread.Start();
         }
         private void DoWorkAsync()
         {
              /* Some long running code */
              btnGo.Invoke(() => { btnGo.Text = "Done"; });
         }




AAP Coding



Comments (3)

read more


12

Indigo Architects goal is to help build great software. To achieve affect a change on the software industry, to help it mature into a modern engineering discipline. We largely focus on the design and architecture phases of software development. As such we are unique in the market.

Nowadays we see a proliferation of excellent ideas in software innovation. The keys to success are found in the execution of these ideas. Delivering a innovative product within a limited time and cost budget is a unique and rare capability.

Indigo Architects has had years of experience in delivering software products.

To name a few