我有一个带有 2 个按钮的表单,这些按钮填充了 2 个不同的 datagridviews。
有一个通用函数接收一条 SQL 语句并执行它。
根据 SQL 语句,这可能需要一些时间来执行 - 因此,我不想锁定 UI,而是使用 BackgroundWorker,这样我就可以在查询运行时显示加载屏幕。
这是没有 BGW 的初始代码:
Public Class Form1
Private Sub Query1Button_Click(sender As System.Object, e As System.EventArgs) Handles Query1Button.Click
Dim sql As String = "SELECT col_1 FROM TABLE_1"
Dim query1DT As DataTable = getData(sql)
'now do some other stuff with the datatable
DataGridView1.DataSource = query2DT
End Sub
Private Sub Query2Button_Click(sender As System.Object, e As System.EventArgs) Handles Query2Button.Click
Dim sql As String = "WHILE 1=1 SELECT col_2 FROM TABLE_2" 'long running query
Dim query2DT As DataTable = getData(sql)
'now do some other stuff with the datatable
DataGridView2.DataSource = query2DT
End Sub
Public Shared Function getData(ByVal sql As String) As DataTable
Dim sqlcon As New SqlClient.SqlConnection
Dim sqlcomm As New SqlClient.SqlCommand
Dim sqlda As New SqlClient.SqlDataAdapter
Dim sqldt As New DataTable
sqlcon.ConnectionString = "DBConnection"
sqlcon.Open()
sqlcomm.Connection = sqlcon
sqlcomm.CommandText = sql
sqlda.SelectCommand = sqlcomm
sqlda.Fill(sqldt)
Return sqldt
End Function
End Class
我想将 getData 函数包装在一个新的 BGW 线程中,但鉴于我要填充两个不同的数据表/数据网格,我不确定该怎么做。
如果只有 1 个数据网格,我会这样做: Imports System.ComponentModel
Public Class Form3
Private Sub Query1Button_Click(sender As System.Object, e As System.EventArgs) Handles Query1Button.Click
Dim sql As String = "SELECT col_1 FROM TABLE_1"
getDataInBackground(sql)
End Sub
Private Sub Query2Button_Click(sender As System.Object, e As System.EventArgs) Handles Query2Button.Click
Dim sql As String = "WHILE 1=1 SELECT col_2 FROM TABLE_2" 'long running query
Dim query2DT As DataTable = getData(sql)
'now do some other stuff with the datatable
DataGridView2.DataSource = query2DT
End Sub
Public Sub getDataInBackground(ByVal sql As String)
'setup worker
Dim bw As BackgroundWorker = New BackgroundWorker()
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, New DoWorkEventHandler(AddressOf bw_DoWork)
AddHandler bw.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf bw_RunWorkerCompleted)
AddHandler bw.ProgressChanged, New ProgressChangedEventHandler(AddressOf bw_ProgressChanged)
'Run worker
bw.RunWorkerAsync(sql)
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim returnDT As DataTable
returnDT = getData(e.Argument)
e.Result = returnDT
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
If e.Cancelled = True Then
StatusLabel.Text = "Cancelled!"
ElseIf e.Error IsNot Nothing Then
StatusLabel.Text = "Error: " & e.Error.Message
Else
'now do some other stuff with the datatable
DataGridView1.DataSource = e.Result
StatusLabel.Text = "Done!"
End If
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
'show loading status
StatusLabel.Text = "Running"
End Sub
Public Shared Function getData(ByVal sql As String) As DataTable
Dim sqlcon As New SqlClient.SqlConnection
Dim sqlcomm As New SqlClient.SqlCommand
Dim sqlda As New SqlClient.SqlDataAdapter
Dim sqldt As New DataTable
sqlcon.ConnectionString = "DBConnection"
sqlcon.Open()
sqlcomm.Connection = sqlcon
sqlcomm.CommandText = sql
sqlda.SelectCommand = sqlcomm
sqlda.Fill(sqldt)
Return sqldt
End Function
End Class
如何使 BGW 更通用,这样我就不必在 bw_RunWorkerCompleted 子中“现在对数据表做一些其他的事情”?