我正在开发一个小型数据库管理工具。我希望应用程序启动并尝试连接到数据库,但数据库驻留在网络驱动器上,因此可能需要很长时间。在此期间,应用程序挂起。
我使用下面的代码尝试运行代码以连接到不同线程中的数据库,以便应用程序可以加载,并且数据库可以单独连接。
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
上述问题是虽然应用程序正确加载并显示表单,但在数据库完成连接之前,用户仍然无法与表单交互。它就像它在另一个线程中运行,但它等待该线程在继续之前完成。
我有什么遗漏或者这不是正确的方法吗?
更新1
感谢您的帮助,我已将代码更新为以下内容并且一切正常:)
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
答案 0 :(得分:2)
将DoEvents()
来电替换为BackgroundWorker
,并将其添加到您的表单中。
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