ARTICLE

Using the BackgroundWorker Component with composite user controls

Posted by Michael Livshitz Articles | Visual Basic 2010 April 21, 2008
In this article you will learn how to use the BackgroundWorker Component with user controls in VB.
 
Reader Level:

Introduction:
 

The .Net allows you to develop and use in your applications new user-defined controls, which can considerably simplify our coding. First of all we should define the kind of the control we want to discuss.

 

In Microsoft documentation it is specified that Windows Forms support three kinds of user-defined controls:

 

  • Composite
  • Extended
  • Custom

A composite controls combine more than one Windows Forms control encapsulated in one unit (a common container). They inherit from the System.Windows.Forms.UserControl class and often are called user controls.

 

An extended control often are called derived or inherited control. We use this control when most of the functionality we need is already identical to an existing Windows Forms control. We just create a class that inherits from the class (Windows Forms control) we have chosen, and overrides or adds properties and methods.

 

A custom control should be created from the beginning by inheriting from the Control class. Here we are going to discuss composite user control (or in short: user control).

 

Using the BackgroundWorker Component allows to run an operation asynchronously. In this article I will show how you can use the BackgroundWorker Component with user controls. The examples are written using C#.

 

Let's create a small project, named "BGW_UC" (that stands for "BackgroundWorker Component and User Controls"). The project includes one windows form, named "Form1", and one folder, named "UC" (that stands for "User Controls"). First of all we add to the UC folder some base control, named "UC_0". Then we add two user controls ("UC_1" and "UC_2"), which inherit from the base control UC_0. You can make it by two ways: or by means of the inheritance picker (fig. 1) or simply to change a line of your code (List. 1):


 

Figure 1.

Namespace BGW_UC.UC

    Partial Public Class UC_2

        Inherits BGW_UC.UC.UC_0

        'UserControl

        Public Sub New()

            InitializeComponent()

        End Sub

    End Class

End Namespace

List 1.
 

We add the BackgroundWorker Component (named "bgw") only to our base control. The UC_1 and UC_2 controls (the derived user controls) gain all the non-private data and behavior (including, of course, the bgw) of the base control (UC_0) in addition to any other data or behaviors they define for themselves.

 

As we have known, the BackgroundWorker Component has three events: DoWork, ProgressChanged and RunWorkerCompleted. We have to use these events in our controls. In addition to it, on some form, where we use our controls, we wish to catch the moment, when these events occur. With this purpose we, first of all, add to the UC_0 the events (for simplicity we add only two events):

 

Public Event BGWDoWork As EventHandler

Public Event BGWCompleted As EventHandler
 

Then we change default methods 
 

Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
 

to
 

Protected Overridable Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
 

and so on.
 

The protected keyword allows to access method within its class and by derived classes, and the virtual keyword allows the methods to be overridden in derived classes. In order to run the RunWorkerAsync method of the BackgroundWorker Component we add the method:

 

Protected Sub RunWoker() 

    bgw.RunWorkerAsync() 

End Sub 

The full text (code) of our base control UC_0 will be the following:

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Drawing

Imports System.Data

Imports System.Text

Imports System.Windows.Forms

 

Namespace BGW_UC.UC

    Partial Public Class UC_0

        Inherits UserControl

        Public Sub New()

            InitializeComponent()

        End Sub

 

#Region "ForClass"

        Public Event BGWDoWork As EventHandler

        Public Event BGWCompleted As EventHandler

#End Region

 

        Protected Overridable Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

            RaiseEvent BGWDoWork(Me, e)

        End Sub

 

        Protected Overridable Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)

 

        End Sub

 

        Protected Overridable Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)

            RaiseEvent BGWCompleted(Me, e)

        End Sub

        Protected Sub RunWoker()

            bgw.RunWorkerAsync()

        End Sub

    End Class

End Namespace
 

OK! Everything is ready to add some functionality to the UC_1 and UC_2.

First of all we add the override methods bgw_DoWork, bgw_ProgressChanged and bgw_RunWorkerCompleted (List 2.).

Partial
Public Class UC_1

    Inherits BGW_UC.UC.UC_0

    'User Control

    Public Sub New()

        InitializeComponent()

    End Sub

 

    Protected Overloads Overrides Sub bgw_DoWork(ByVal sender As Object, ByVal E As DoWorkEventArgs)

        MyBase.bgw_DoWork(sender, E)

    End Sub

    Protected Overloads Overrides Sub (ByVal bgw_RunWorkerCompleted As bgw_RunWorkerCompleted)

    End Sub

End Class

List 2.

 

To start our asynchronous operation we use for the UC_1 the method  

 

Public Sub LoadData() 

    MyBase.RunWoker() 

End Sub 

And for the UC_2 the click_button event (preliminary having added the button1 to the UC_2):

       

Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) 

    MyBase.RunWoker() 

End Sub 

In order to simulate database transactions (of course, you can connect to real database; this simulation is only for our test purpose) we use GetData.dll. With this purpose we add reference to GetData.dll and add two lines of code to the bgw_DoWork method:

Dim getData As New GetData.GetDataHelp () 

Dim dt As DataTable = getData.getDataSetCities(1000000).Tables(0)

The full text (code) of the UC_1 control will be the following:

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Data

Imports System.Drawing

Imports System.Text

Imports System.Windows.Forms

 

Namespace BGW_UC.UC

    Partial Public Class UC_1

        Inherits BGW_UC.UC.UC_0

        Public Sub New()

            InitializeComponent()

        End Sub

        Protected Overloads Overrides Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

            MyBase.bgw_DoWork(sender, e)

            Dim getData As New GetData.GetDataHelp()

            Dim dt As DataTable = getData.getDataSetCities(1000000).Tables(0)

        End Sub

        Protected Overloads Overrides Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)

            MyBase.bgw_ProgressChanged(sender, e)

        End Sub

        Protected Overloads Overrides Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)

            MyBase.bgw_RunWorkerCompleted(sender, e)

        End Sub

 

        Public Sub LoadData()

            MyBase.RunWoker()

        End Sub

    End Class

End Namespace

 

The full text (code) of the UC_2 control will be the following:

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Drawing

Imports System.Data

Imports System.Text

Imports System.Windows.Forms

 

Namespace BGW_UC.UC

    Partial Public Class UC_2

        Inherits BGW_UC.UC.UC_0

        'UserControl

        Public Sub New()

            InitializeComponent()

        End Sub

        Protected Overloads Overrides Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

            MyBase.bgw_DoWork(sender, e)

            Dim getData As New GetData.GetDataHelp()

            Dim dt As DataTable = getData.getDataSetCities(1000000).Tables(0)

        End Sub

        Protected Overloads Overrides Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)

            MyBase.bgw_ProgressChanged(sender, e)

        End Sub

        Protected Overloads Overrides Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)

            MyBase.bgw_RunWorkerCompleted(sender, e)

        End Sub

 

        Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)

            MyBase.RunWoker()

        End Sub

    End Class

End Namespace 

OK! Now we add to the Form1 the follow control: UC_1 (named "UC_11"), UC_2 (UC_21), button (button1), statusStrips (statusStrip1 and statusStrip2); to the statusStrip1 we add toolStripStatusLabel1 and to the statusStrip2-toolStripStatusLabel2.

 

To catch the beginning and finish of the data loading we use the BGWDoWork and BGMCompleted events (fig. 2):


 

Figure 2.

 

The full text (code) of the Form1 will be the following:

 

Imports System

Imports System.Collections.Generic

Imports System.ComponentModel

Imports System.Data

Imports System.Drawing

Imports System.Text

Imports System.Windows.Forms

 

Namespace BGW_UC

    Partial Public Class Form1

        Inherits Form

        Public Sub New()

            InitializeComponent()

        End Sub

 

        Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)

            uC_11.LoadData()

        End Sub

 

        Private Sub uC_11_BGWCompleted(ByVal sender As Object, ByVal e As EventArgs)

            toolStripStatusLabel1.Text = "End...UC_1"

        End Sub

 

        Private Sub uC_11_BGWDoWork(ByVal sender As Object, ByVal e As EventArgs)

            toolStripStatusLabel1.Text = "Load...UC_1"

        End Sub

 

        Private Sub uC_21_BGWCompleted(ByVal sender As Object, ByVal e As EventArgs)

            toolStripStatusLabel2.Text = "End...UC_2"

        End Sub

 

        Private Sub uC_21_BGWDoWork(ByVal sender As Object, ByVal e As EventArgs)

            toolStripStatusLabel2.Text = "Load...UC_2"

        End Sub

    End Class

End Namespace
 

As you can see, now we have possibility to test two independent time-consuming processes: the first one we start with the help of the button of the Form1 (for the UC_1), the second process we start with the help of the button of the control itself (for the UC_2). Run the project, click on the "Load UC_1" button. You can see that the first loading starts. But our user interface does not hang. Click on the "Load UC_2" button. Now two processes are running (fig. 3).



Figure 3.
 

In some seconds the first process comes to an end (fig. 4) and then the second (fig. 5).


Figure 4.


 

Figure 5.

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# Corner (http://www.c-sharpcorner.com/).

Login to add your contents and source code to this article
share this article :
post comment
 
Team Foundation Server Hosting
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
Team Foundation Server Hosting
Become a Sponsor