Saturday, June 12, 2010

BackGroundWorker example

I’ve seen a lot of questions lately on forums about the BackGroundWorker (BGW) Class and how to use it. The BGW’s purpose is to execute an operation on a separate thread. Whenever you have a time-consuming operation that need to be executed you can use a BGW to avoid having your User Interface (UI) stop responding. It is a convenient solution if you only have a single time-consuming operation to execute. If you have multiple time-consuming operations that you would like to execute at the same time, then I suggest you have a look at the ThreadPool Class.

Here’s a small example in VB.NET that shows how to use the BGW to perform an SQL query while the first Form show a progress bar and then displays the second Form once the SQL operation as completed.

Imports System.Data.OleDb

Module Module1
    Public da As New OleDbDataAdapter
    Public ds As New DataSet
End Module

Imports System.Text
Imports System.Collections
Imports System.ComponentModel
Imports System.Data.OleDb


Public Class Form1
    Dim WithEvents bgw As New BackgroundWorker
    Delegate Sub HideButtonDelegate()
    Public HBD As HideButtonDelegate = AddressOf Me.HideButton

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        bgw.WorkerSupportsCancellation = True
        ProgressBar1.Show()
        bgw.RunWorkerAsync()
    End Sub

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgw.DoWork
        'Do your lenghty operations here

        Dim MyConnection As New System.Data.OleDb.OleDbConnection()
        Dim MyCommand As OleDbCommand


        Try
            MyConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data source=" & Application.StartupPath & "\Database1.accdb"
            MyConnection.Open()
        Catch ex As Exception
            MessageBox.Show("Cannot connect to the specified database" & ex.Message)
        End Try

        Try
            MyCommand = New OleDbCommand("SELECT * FROM Table1", MyConnection)
            da.SelectCommand = MyCommand
            ds = New DataSet
            da.Fill(ds, "Table1")
        Catch ex As Exception
            MessageBox.Show("Cannot fetch data from the database" & ex.Message)
        End Try
        System.Threading.Thread.Sleep(2000)
        If Button1.InvokeRequired Then
            Me.Invoke(HBD)
        End If

        System.Threading.Thread.Sleep(2000)

    End Sub


    Private Sub bgw_Completed(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs) Handles bgw.RunWorkerCompleted
        ProgressBar1.Hide()
        Me.Hide()
        Form2.Show()
    End Sub

    Private Sub HideButton()
        Button1.Visible = False
    End Sub
End Class

Public Class Form2

    Private Sub Form2_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        Form1.Close()
    End Sub

    Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        DataGridView1.DataSource = ds.Tables(0)
    End Sub
End Class