Responsive User Interfaces with UI Threads

Have you ever seen this exception and wondered “Huh !! wtf is that suppose to mean ?”

exception.jpg

Cross-thread operation not valid: Control ‘Form1’ accessed from a thread other than the thread it was created on.”?? Or you want to update a UI of a windows based application in real time. The classis scenario for this is the stock market applications or processing credit cards from windows based application or while making web service calls synchronously where at many places the real time updates to the UI is absolutely essential.As an application developer / designer you might have encountered situations where The UI of the application gets updated After a COM Component Call or a Web service call or some extensive processing with the data. If this takes too long the User Interface of your application stops responding and hangs which is the first thing people notice and criticize in spite of the efficient code you have written in the business logic for processing complex data !! One possible solution of handling all such scenarios is to update the UI of your Application from a separate thread. The thread would be responsible to update any UI on your forms and another thread would be processing the data simultaneously.I had this idea and when I tried to access windows controls from the newly created thread I had the exception which I have mentioned. I did some research on this and realized that “A control cannot be accessed from any other thread but the thread they were created on “. So for accessing UI elements from a different thread I have made a small framework which you can also use..Net provides a mechanism for this and it’s extremely simple. I think in the upcoming versions of .Net the background worker control would be more powerful and synchronization would be an included feature. So we don’t have to worry about any of it.For now I would just indicate how to update or access the UI from a different thread other than the main Application thread. My sample application is a VC# windows application compiled with .Net 2005 IDE and uses .Net 2 frameworks.I would just give you a step by step description instead of excerpts to make it more easy and understandable.The first thing we need to do is to create a System.Threading.Thread instance. It may be good to make it a form level variable since it might be accessed from different places on your form.ui.jpg

System.Threading.Thread  myThread;In the Constructor or any other suitable place initialize the Thread instance. The constructor is overloaded and I mostly use that takes the ThreadStart instance so I pass a new instance like: 

myThread = new Thread(new ThreadStart(ThreadProc));

 Note: Thread Start is a delegate and requires a target method which it points to and can be called once the thread is running.Now make a no argument method with the same name as you passed in the ThreadStart constructor:
public void ThreadProc()
{

   try
   {

        int count = 0;

        MethodInvoker mi;
        mi= MethodInvoker
(Updater);   

while (globalcount  < 300) 
  
{
         
     this.BeginInvoke(mi);

     Thread.Sleep(500);
         
  }
    
}

catch (Exception ex)    { // do nothing    }

}

We observe that we use another delegate “Method Invoker” which is the key basically. We make an instance of MethodInvoker delegate and pass a no argument method from which we access the UI of the form. After that we call the “BeginInvoke” of our main form and pass the instance of method Invoker.Note: As Method Invoker is also a delegate, we also need to specify the target method. In this case this would be the method from where UI is accessed. 

public void Updater()
{
   this.Text = globalcount.ToString();            
}

Once we are done with all of that all we have to do is to start the thread, so we would just call myThread.Start( ) ,and we are all set up.This way of updating the UI is also efficient in the sense that it is performed asynchronously instead of updating on timers or some other undesirable synchronous way.

 Want more sample code / applications feel free to contact me 🙂 If you have some good design ideas, I would love to hear it!! also post ur comments if there is something specific u r looking for , thanks . If you need examples with C# or java where you wanna update your UI from a different threads I have the code available for you … fell free to discuss here or if this was of any use or not , i would appreciate your feedback !!

My email address is hiasad@hotmail.com

Advertisements

18 Comments

Filed under C#

18 responses to “Responsive User Interfaces with UI Threads

  1. anonymus

    Thanks for your post, it’s really help me.

    Best wishes.

  2. GymnElamn

    Hello my friends 🙂
    😉

  3. Dilip Joshi

    Hey Hi,

    This article really helped me. Thanks for the same.

    Rgds

  4. Arthur Kahwa

    Thanks for this post,
    it has saved me a whole lot of research and experimentation.

    Arthur

  5. Mikae

    Hi m8 , thx for input..

    Just one qustion …

    When I have my thredd running , and putting it in suspend mode for reading on screen, and then start it works fine. But if i want to kill application (thredd.abort()), then I got a Exeption if the thredd is suspended, but not if it’s running ??? do u have a solution for this ??

    best regards Mikael

  6. asadsiddiqi

    ” When I have my thredd running , and putting it in suspend mode for reading on screen, and then start it works fine. But if i want to kill application (thredd.abort()), then I got a Exeption if the thredd is suspended, but not if it’s running ??? do u have a solution for this ??”

    Mikael,
    You cannot abort a thread when it is suspended. You can check the thread state before calling the abort method and only abort if it is not suspended. If you want a hard abort anyways, Change the state from suspended to idle or something and then abort it !!

    Hope this helps …

  7. Mikae

    Okej, thx !
    Mikael

  8. Rishabh

    Awesome!!! thx a lot…. it really helps

  9. Komin

    This piece worked perfectly for me. But I’ve an unrelated question about threading. I’m trying to read i/p from 2 card readers where one is in the thread and the other is in the main thread.

    I cannot but get the two threads to work concurrently. Either the 1st reader reads it or the second reader alone works. Do you know how could I fix it. and both readers are HID.

    • asadsiddiqi

      Komin,
      Sounds to me as if your card readers work in xclusive mode. This wouldnt be an issue with threads but the card reader.
      I dont think it would let two threads or two applications access itself at the same moment. I am not sure of what you are referring too but this is the closest as I can think. I work with OPOS card readers and my application has to claim the device before it can be used or an API Call. So the device is exclusively claimed by a thread( API Call) and would restrict the access or Lock itself before the processing is completed.
      There might be other ways you can work around the problem but i cannot think of a scenario where u need different threads for a card reader. I guess you can design it in a different way to make it faster (Instead of using card reader in a thread, use the card reader in the main thread. Once you have read the data, pass it to a thread to process it and the main thread continues to take more input). Hope this helps.
      Thanks

  10. Komin

    I played with the code for awhile and found that the threads work fine. If I call first swiper-thread and the 2nd swiper-thread in the main program, I can handle swipes twice but only from the second swiper. If I change the order of the calls..when the first swiper thread is called second, then it handles swipes twice from the first swiper.

    The HID handles are not being changed. Do you know what is the problem?

  11. Excellent site asadsiddiqi.wordpress.com and I am really pleased to see you have what I am actually looking for here and this this post is exactly what I am interested in. It’s taken me literally 2 hours and 15 minutes of searching the web to find you (just kidding!) so I shall be pleased to become a regular visitor 🙂

  12. Arush

    Just put this code in ur constructor class:

    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;

  13. Paul

    Hello Mr. Hemmath
    with all due respect, this worked for us,
    but can you provide another solution,
    because you said that this is a poor programming.

  14. Paul

    and thanks to this post it saves me

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s