我正在使用Windows窗体应用程序:
在我的形式我在某个时间间隔填充我的数据网格视图。所以有一段时间我的应用程序卡住..所以我用了地面工人和计时器
在后台工作人员我调用我的函数来填充我的数据网格视图。我将Timer Interval设置为10000 。在后台工作者我给这样的代码:
Private Sub BackgroundWorker1_DoWork
Call Fetch_Info()
End Sub
在计时器点击事件中我给出了像这样的代码:
If Not BackgroundWorker1.IsBusy Then
BackgroundWorker1.RunWorkerAsync()
End If
我的Fetch_Info()函数如下:
Dim cnt As Integer
Dim tbarcodedgv As String
Dim totaltbarcode As String
cnt = DGVall.RowCount
Dim tbar As String
Dim locTable As New DataTable
locTable.Columns.Add("carid", GetType(String))
If cnt > 0 Then
For i = 0 To cnt - 2
tbarcodedgv = DGVall.Rows(i).Cells(0).Value
locTable.Rows.Add(tbarcodedgv)
Next
End If
Dim flag As Boolean = False
Dim dcnt As Integer = DGVall.RowCount
Dim trid As Integer
Dim tbarcode As String
Dim keyloc As String
Dim cmd23 As New SqlCommand("IBS_fetchrequested", con.connect)
cmd23.CommandType = CommandType.StoredProcedure
cmd23.Parameters.Add("@tid", SqlDbType.Int).Value = tid
If cnt > 1 Then
Dim tvp1 As SqlParameter = cmd23.Parameters.AddWithValue("@Tbaroced", locTable)
tvp1.SqlDbType = SqlDbType.Structured
tvp1.TypeName = "dbo.TBarcode"
End If
dr = cmd23.ExecuteReader
While dr.Read
flag = False
tbarcode = dr("TBarcode")
If flag = False Then
If dr("keyloc") Is DBNull.Value Then
keyloc = ""
Else
keyloc = dr("keyloc")
End If
Dim row0 As String() = {tbarcode, keyloc, "", "Release"}
DGVall.Rows.Add(row0)
AxWindowsMediaPlayer1.URL = "C:\Beep.mp3"
End If
End While
dr.Close()
con.disconnect()
答案 0 :(得分:1)
当你的后台工作程序运行在除GUI之外的另一个线程中时,你正在操纵在GUI的线程中运行的Datagridview。这应该通常根本不起作用,但这可能是为什么你的GUI在BGW运行时挂起的原因。
尝试拆分工作:从Backgroundworker的DoWork
事件处理程序中执行从数据库中获取数据的耗时,并将结果设置为EventArgs变量的e.Result值。 DoWork功能。
然后,您处理了Backgroundworker的RunWorkerCompleted
事件,并在那里使用您在DoWork方法中设置的结果快速更新datagridview。这样,您的GUI与实际耗时的任务无关,只会受到数据网格视图快速更新的影响。
这个代码示例是:
Public Class Form1
Private WithEvents LazyBGW As New System.ComponentModel.BackgroundWorker
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'This code runs in the UI-Thread
LazyBGW.RunWorkerAsync()
End Sub
Private Sub LazyBGW_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles LazyBGW.DoWork
'This code runs in the BGW-Thread
Dim a As Integer = 0
For i = 1 To 5
a += 1
'I'm a lazy worker, so after this hard work I need to...
Threading.Thread.Sleep(1000) 'This locks up the BGW-Thread, not the UI-thread
Next
'Work is done, put results in the eventargs-variable for further processing
e.Result = a
End Sub
Private Sub LazyBGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles LazyBGW.RunWorkerCompleted
'This code runs in the UI-Thread
Dim results As Integer = CInt(e.Result) 'e.Result contains whatever you put into it in the DoWork() method
MessageBox.Show("Finally the worker is done and our result is: " & results.ToString)
End Sub
End Class