Thursday, 23 October 2008

Form Creation and BackgroundWorker processes

When a form is loaded/created... there are many events which take place throughout its creation phase.

Have you ever been in a position where you want something to trigger as soon as the application opens? Im sure you all have, in which case, code is placed within the 'Load' event handler for the associated form object. However, this event is triggered before the actual form is rendered to the user. What if we want the form to physically load (paint) before events are triggered?

We then could use the "Shown" event of the form object... once the form is 'shown' to the user, we can then perform some actions. This is also quite useful, but if your form contains many complex controls and images, then you might see a form which has been "half-generated" before the application starts (this would be useless if this form was, for example, a splashscreen").

We then look into "BackgroundWorker" objects. When dealing with .NET windows forms, these objects are available to us within the toolbar. Simply drag one onto your form and give it a name...

BackgroundWorker objects, in their simplest, are threads running alongside our main thread to process information (Mainly GUI creation) in the background. This allows the form to load and display its information fluently while the background processes are carried out on a seperate thread in the background.

To use this feature, we need to do the following:
1. override the events available from the control.
These are:
"DoWork" - This is triggered first and contains the 'work' to take place. This
could be a call to a function which contains web service consumption and other
"ReportProgress" - This allows us to report progress back to the user.
"RunWorkerCompleted" - This event triggers when the 'work' has finished.

The "ReportProgress" event is useful if we wish to use a status bar of the progress, but generally, we only need the following 2 events...

this.bkWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(bkWorker_DoWork);
this.bkWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bkWorker_RunWorkerCompleted);

To trigger the DoWork event, we call the "RunWorkerAsync()" function of the BackgroundWorker object. If we wish to pass parameters, we can retrieve them in
the DoWork event by referencing the DoWorkEventArgs parameter.

The DoWorkEventArgs parameter allows us to control and pass information between the worker object and the main windows form. e.Argument (Where e is a reference to the DoWorkEventArgs object) is used to retrieve the passed parameter. We can then store results within the e.Result data member.

e.Result can then be retrieved when the RunWorkerCompleted event is triggered and the GUI can be updated appropriately.

Note: We must not reference the form within the "DoWork" event. This is merely for processing only. We can however utilise the GUI objects from the main thread within the other events. This is why we use DoWorkEventArgs to store result information.