SilverShotBee SilverShotBee - 5 months ago 14
Vb.net Question

VB.Net Running a task on a different thread

I'm developing a small database management tool. I'd like the application to start up and attempt to connect to the database, but the database resides on a networked drive, so it can take a long time. During this time, the application hangs.

I'm using the below code to try and run the code to connect to the database in a different thread so that the application can load, and the database can connect separately.

Public Class Incident_Form

'DELEGATE CLASSES
Delegate Sub UpdateTable()

'DELEGATE VARIABLES
Public UpdateTableVar As UpdateTable

Private Sub Incident_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load


I_List.DataSource = Nothing
Display_Module.Maximise_Window()

Splash_Panel.BringToFront()

System.Windows.Forms.Application.DoEvents()

UpdateTableVar = New UpdateTable(AddressOf Me.UpdateTableHandler)

Me.Invoke(Me.UpdateTableVar)


End Sub



Public Sub UpdateTableHandler() 'Handles the background work for updating I_LIST
If (Me.InvokeRequired) Then
Me.Invoke(UpdateTableVar)
Else
Dim myCon = New OleDbConnection(My.Settings.Database_Connection_String)
myCon.Open()

Dim ds As DataSet = New DataSet
Dim adapter As New OleDb.OleDbDataAdapter
Dim sql As String

sql = "SELECT [IN_REF], [Incident Name], [Date Created], [Created By] " & _
"FROM [Master_Record]"

adapter.SelectCommand = New OleDb.OleDbCommand(sql, myCon)
adapter.Fill(ds)
I_List.DataSource = ds.Tables(0)

I_List.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
I_List.Columns(0).HeaderText = "Reference"

I_List.Sort(I_List.Columns("Date Created"), System.ComponentModel.ListSortDirection.Descending)

myCon.Close()
End If
End Sub


The issue with the above is that although the application loads and displays the form correctly, the user still cannot interact with the form until the database finishes connecting. It's like it's running in another thread but its waiting for that thread to finish before it continues.

Is there something I'm missing or is this not the correct approach?

UPDATE 1

Thanks for the help, I've updated the code to the following and all is working correctly :)

Public Class Incident_Form

Dim ds As DataSet = New DataSet





Private Sub Incident_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load


I_List.DataSource = Nothing
Display_Module.Maximise_Window()
Splash_Panel.BringToFront()
System.Windows.Forms.Application.DoEvents()
Try
BackgroundWorker1.RunWorkerAsync()
Catch ex As Exception
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.CancelAsync()
End Try




End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

UpdateTableHandler()

End Sub


Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
I_List.DataSource = ds.Tables(0)

I_List.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
I_List.Columns(0).HeaderText = "Reference"

I_List.Sort(I_List.Columns("Date Created"), System.ComponentModel.ListSortDirection.Descending)
End Sub


Public Sub UpdateTableHandler() 'Handles the background work for updating I_LIST

Dim myCon = New OleDbConnection(My.Settings.Database_Connection_String)
myCon.Open()


Dim adapter As New OleDb.OleDbDataAdapter
Dim sql As String

sql = "SELECT [IN_REF], [Incident Name], [Date Created], [Created By] " & _
"FROM [Master_Record]"

adapter.SelectCommand = New OleDb.OleDbCommand(sql, myCon)
adapter.Fill(ds)


myCon.Close()

End Sub

Answer

Replace your DoEvents() call with BackgroundWorker by adding it to your form.

Private Sub Incident_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    I_List.DataSource = Nothing
    Display_Module.Maximise_Window()
    Splash_Panel.BringToFront()

    Try
        BackgroundWorker1.RunWorkerAsync()    
    Catch ex As Exception
        BackgroundWorker1p.WorkerSupportsCancellation = True
        BackgroundWorker1.CancelAsync()
    End Try
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As 
System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    UpdateTableHandler()

End Sub
Comments