Main Menu
Knowledge Base
Product Registration
Log an Incident
Request a Feature
Search Incidents/Bug Reports


Search KB

Please note: In an effort to better serve you, we are in the process of restructuring DevCenter. In the process, we have moved many items that you may be used to finding in DevCenter over to the Main Site. If you are having trouble locating something, please try looking at the following places:

Knowledge Base Article: KB09839

HOWTO:Using the Background Worker component with the WinGrid to get data asynchronously CLR2 [Part 2]


The information in this article applies to:
UltraWinGrid (v6.1.20061)
  Article Created: 
4/19/2006

Last Updated:
4/19/2006

Article Type
How To
  
Page Options
Average Rating:
8 out of 10

Rate this page
Print this page
E-mail this page
Add to Favorites

Summary

This article will show you how to safely get data into a WinGrid using the Background Worker component found in .NET 2.0

Step-By-Step Example

..Continued

Whenever we invoke the “ReportProgress( )” method, the event “ProgressChanged” fires for us to execute some code on the User Interface thread.

C#

        private void bgwData_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            _customers.Add(e.UserState as Customer);

            if (e.ProgressPercentage <= this.ultraProgressBar1.Maximum)
            {
                this.ultraProgressBar1.Value = e.ProgressPercentage;
            }
        }

VB.NET

    Private Sub bgwData_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwData.ProgressChanged
        _customers.Add(DirectCast(e.UserState, Customer))

        If e.ProgressPercentage <= Me.ultraProgressBar1.Maximum Then

            Me.ultraProgressBar1.Value = e.ProgressPercentage
        End If
    End Sub

Notice how simple it is to use the event arguments available in the event handler. We can get the current progress value and assign it to the progress bar (note: we are working with values of 0 to 100 so we can use the loop indexer, if we were not dealing with such numbers, you need to convert your values using mathematics so that the end result would be a percentage of 100). We can also access the Customer object that we passed by using the e.UserState property.

The ProgressChanged event will fire once per call of the Background Worker’s invocation of the “ReportStatus( )” method and each time it does fire, a new Customer is added to the WinGrid and the Progress Bar increments.

The last Background Worker event that we need to handle is the RunWorkerCompleted event which fires whenever the thread has completed (either naturally or from being cancelled)

C#

        private void bgwData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.btnGetData.Enabled = true;
            this.lblMessage.Text = "Retrieval Complete. Total Records: " + _customers.Count.ToString();
        }

VB.NET

    Private Sub bgwData_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwData.RunWorkerCompleted
        Me.btnGetData.Enabled = True
        Me.lblMessage.Text = "Retrieval Complete. Total Records: " + _customers.Count.ToString()
    End Sub

This is the perfect event to place code to reset and enable elements on the user interface that were previously disabled while the thread was running.

In order to cancel the Background Worker from running we need to call its “CancelAsync( )” method. This stops the process from running. It is a good idea to first test to see if it is running first as shown in the code below:

C#

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (this.bgwData.IsBusy) this.bgwData.CancelAsync();
        }


        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.bgwData.IsBusy) this.bgwData.CancelAsync();
        }

VB.NET

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        If Me.bgwData.IsBusy Then Me.bgwData.CancelAsync()
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If Me.bgwData.IsBusy Then Me.bgwData.CancelAsync()
    End Sub

Notice how the same code is being called in both the Cancel button’s Click event as well as the FormClosing event. If you do not execute this code from the FormClosing event, any running process will still continue once the form is closed and the Background Worker will still attempt to connect and write to the form that is no longer there. Closing this in this fashion solves that problem.

Review:
Thanks to the wonderful new Background Worker component by the Microsoft team, we are now able to perform multi threading tasks with great ease and safety. Getting Data into the WinGrid from a separate background thread is now easier more than ever and is a great way to keep the user interface responsive during those long database queries. Please download the included examples to see a working implementation.

Related Articles

HOWTO: Using the Background Worker component with the WinGrid to get data asynchronously CLR2 [Part 1] (KB09838)

Samples

wingrid_background_worker.zip
 Sample Application for Background Worker Component and WinGrid



How would you rate the quality of this content?
Poor -----------------------------------------> Outstanding

Tell us why you rated the content this way. (optional)