Search code examples
vb.netwinformsbackgroundworkerloading

Show "loading form" while retrieving data


I have a large application in which I would like to implement a loading screen. This pops up every time user requests large sets of data. While the database is retrieving the data, the user sees a small form with the text "Please wait" and a gif progressbar-like thingy.

The problem I encounter is that I launch this form in a second thread using a backgroundworker. This is fine, I see it pop up, but it doens't close when the loading is done. I used the code supplied by microsoft MSDN. This is the code I have now, but the closing never happens. I debugged the code, and see that the bgw.cancellationpending never gets to true, even though I call the CancelAsync() method.

showLoading is called before the database call, cancelLoading() is called after the database call is completed.

What is wrong and what should I change?

My code:

Private bgw As New BackgroundWorker

Public Sub showLoading()
    bgw.WorkerSupportsCancellation = True

    AddHandler bgw.DoWork, AddressOf bgw_doWork
    AddHandler bgw.RunWorkerCompleted, AddressOf bgw_Complete

    If Not bgw.IsBusy = True Then
        bgw.RunWorkerAsync()
    End If
End Sub

Public Sub closeLoading()
    If bgw.WorkerSupportsCancellation = True Then
        bgw.CancelAsync()
    End If
End Sub

Private Sub bgw_doWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    Dim loadingScreen As New frmLoading

    loadingScreen.ShowDialog()

    While True
        If Not bgw.CancellationPending Then
            Threading.Thread.Sleep(50)
        Else
            e.Cancel = True
            Exit While
        End If
    End While
End Sub

Private Sub bgw_Complete(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    Dim lstFrm As New List(Of frmLoading)
    lstFrm = Application.OpenForms.OfType(Of frmLoading)()

    If lstFrm.Count > 0 Then
        For Each frm As frmLoading In lstFrm
            frm.Close()
        Next
    End If
End Sub

Solution

  • Your problem seems to be loadingScreen.ShowDialog().

    Use loadingScreen.Show() as .ShowDialog() blocks the execution as long as the Dialog stays open.