Accessing GUI control from worker thread was always a problem in Windows OS. This problem
did not go away with introduction of C#. Here I offer simple demo of how to manipulate GUI
controls from the worker thread. The program demonstrates Central Limit Theorem from statistics|
It uses random digit generator to simulate outcome of rolling one die. The distribution is uniform. But when several dice are rolled and outcomes are added the distribution is radically changed and when 3 and more dice involved it start approaching normal distribution. Being more scientific, with small number of dice it is supposed to be Student distribution and turn into normal when number of dice is large enough.
User can select number of dice and size of sequence and start worker thread that performs computations. During computation user can manipulate other controls, terminate thread and application. When thread finished computations the histogram of distribution of sums of selected number of dice values is drawn. The thread should also enable/disable of some buttons allow or disallow user to use certain controls according to a thread state. It also controls the progress bar at the bottom.
The GUI thread is always conflicting with worker thread in Windows applications. And in many applications programmer wants to start worker thread and keep GUI controls responsive to user actions while computation continues. It also would be nice to have this worker thread to report its state by the progress bar or other. There are several ways of achieving this goal. One of them is to pass GUI object and delegate to worker thread and call Invoke method of GUI object inside the worker thread. It may be more clear when looking at several formal operation we need to perform in order to achieve the goal.
In the code above you can see only critical operations required for accessing GUI control from worker thread. They are:
There are some other methods of calling GUI from worker thread. I added one alternative method and tested but don't use it in my example. That does not mean that method is not good. This method simplify calls by introduction of static helper class SaveInvokeHelper. The usage is obvious from the code. It may look simpler because when calling SaveInvokeHelper there is no need to create and pass delegates. Unfortunately, SaveInvokeHelper works with Form object only and has to be changed to support also Control object, while the method shown above works in the same way with every particular Control object.