#vb.net
#vb.net
Вопрос:
У меня есть некоторые проблемы с моим кодом, я могу отлично извлекать данные из базы данных без каких-либо зависаний, но после завершения выборки, и я хочу добавить выбранные данные в представление сетки, программа зависнет, даже если я уже ввел код внутри фонового рабочего.
Вот код для объявления таблицы, я использую данные сетки DevExpress, если вам это интересно.
Dim Table1 As DataTable
Dim ItemCode As String = ""
Dim ItemName As String = ""
Dim BrandName As String = ""
Dim FamilyName As String = ""
Dim SubFamilyName As String = ""
Sub loadtabel()
Table1 = New DataTable("myTable")
Table1.Columns.Add(CreateColumn("ItemCode", "str"))
Table1.Columns.Add(CreateColumn("ItemName", "str"))
Table1.Columns.Add(CreateColumn("BrandName", "str"))
Table1.Columns.Add(CreateColumn("Quantity", "int"))
Table1.Columns.Add(CreateColumn("UOM", "str"))
Table1.Columns.Add(CreateColumn("FamilyName", "str"))
Table1.Columns.Add(CreateColumn("SubFamilyName", "str"))
dgvTabel.DataSource = Table1
End Sub
Вот моя функция для запуска моего фонового рабочего
Sub LoadData(ByVal varItemCode As String, ByVal varItemName As String, ByVal varBrandName As String, ByVal varFamilyName As String, ByVal varSubFamilyName As String)
loadtabel()
If BackgroundWorker1.IsBusy Then
Exit Sub
End If
ItemCode = ""
ItemName = ""
BrandName = ""
FamilyName = ""
SubFamilyName = ""
If varItemCode <> "" Then ItemCode = varItemCode
If varItemName <> "" Then ItemName = varItemName
If varBrandName <> "" Then BrandName = varBrandName
If varFamilyName <> "" Then FamilyName = varFamilyName
If varSubFamilyName <> "" Then SubFamilyName = varSubFamilyName
pbLoading.Visible = True
lblLoading.Text = "Fetching Data, Please Wait..."
BackgroundWorker1.RunWorkerAsync()
End Sub
И вот мой запрос BackgroundWorker, здесь я также выполняю выборку данных. извлечение данных из самой базы данных занимает до 11 секунд. Около более 20 000 данных. но поскольку я использую фоновый рабочий, он извлекается плавно, без зависания.
Private Sub bgwSuburbs_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim request As HttpWebRequest
Dim reader As StreamReader
Dim postData As String = ""
Dim UrlPrefix = "http://" amp; My.Settings.SharedConnection amp; ":" amp; My.Settings.SharedURLPort
request = DirectCast(WebRequest.Create(UrlPrefix amp; "/hotraxpos/item_list.php"), HttpWebRequest)
postData = "itemcode=" amp; ItemCode amp;
"amp;itemname=" amp; ItemName amp;
"amp;brandname=" amp; BrandName amp;
"amp;familyname=" amp; FamilyName amp;
"amp;subfamilyname=" amp; SubFamilyName amp;
"amp;device_data=HC ALL IN ONE"
request.Method = "POST"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = byteArray.Length
Dim dataStream As Stream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim response As WebResponse = request.GetResponse()
reader = New StreamReader(response.GetResponseStream())
Dim rawresp As String
rawresp = reader.ReadToEnd()
Dim array As JArray = JArray.Parse(rawresp)
'IF I EXCLUDE CODE FROM HERE, THE BACKGROUND WORKER WORK NORMALLY WITHOUT FREEZING
Me.Invoke(Sub()
For Each item As JObject In array
Dim status As String = If(item("Status") Is Nothing, "", item("Status").ToString())
Dim Keterangan As String = If(item("Keterangan") Is Nothing, "", item("Keterangan").ToString())
Console.WriteLine("Keterangan: " amp; Keterangan)
If status = "SUCCESS" Then
Dim varItemCode = If(item("ItemCode") Is Nothing, 0, item("ItemCode").ToString)
Dim varItemName = If(item("ItemName") Is Nothing, 0, item("ItemName").ToString)
Dim varBrandName = If(item("BrandName") Is Nothing, 0, item("BrandName").ToString)
Dim varQuantity = If(item("Quantity") Is Nothing, 0, Val(item("Quantity").ToString))
Dim varUOM = If(item("UOM") Is Nothing, 0, item("UOM").ToString)
Dim varFamilyName = If(item("FamilyName") Is Nothing, 0, item("FamilyName").ToString)
Dim varSubFamilyName = If(item("SubFamilyName") Is Nothing, 0, item("SubFamilyName").ToString)
Dim Row1 As DataRow
Row1 = Table1.NewRow()
Row1.Item("ItemCode") = varItemCode
Row1.Item("ItemName") = varItemName
Row1.Item("BrandName") = varBrandName
Row1.Item("Quantity") = varQuantity
Row1.Item("UOM") = varUOM
Row1.Item("FamilyName") = varFamilyName
Row1.Item("SubFamilyName") = varSubFamilyName
Table1.Rows.Add(Row1)
End If
Next
dgvTabel.DataSource = Table1
End Sub)
End Sub
Private Sub bgwSuburbs_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
pbLoading.Visible = False
lblLoading.Text = "Done"
End Sub
Как я уже упоминал выше, если я удалю код Me.Invoke(Sub()
внутри фонового рабочего DoWork, он отлично работает без зависания, но также и без отображения каких-либо данных…
пожалуйста, помогите, мне просто нужно знать, как также заполнить datagridview без зависания с помощью background worker. как мне это сделать?
Комментарии:
1. Не используйте
Me.Invoke()
. Кроме того, не назначайте источник данных в методе loadtabel(). Вместо этого назначьте его только в событии RunWorkerCompleted(), затем аннулируйте () DataGridView, чтобы он обновился. В зависимости от того, сколько данных у вас в таблице, может возникнуть задержка. Если это неприемлемо, тогда загружайте МЕНЬШЕ данных за раз и предоставляйте пользователю механизм для просмотра данных. Похоже, вы назначили источник данных в нескольких местах. Опять же, назначайте его только в событии RunWorkerCompleted() .2. В дополнение к комментарию @Idle_Mind, вы должны заполнить
DataTable
в обработчикеDoWork
событий, чтобы это делалось в фоновом потоке. Затем вы присваиваете егоe.Result
свойству, а затем возвращаете его изe.Result
свойства в обработчикеRunWorkerCompleted
событий. Назначение этогоDataTable
дляDataSource
сетки — единственное действие, которое вы выполняете в потоке пользовательского интерфейса.3. @jmcilhinney если я заполню DataTable в DoWork, как присвоить его e.Result и получить его из RunWorkerCompleted, как вы сказали? не могли бы вы помочь мне здесь
4.
e.Result
это просто свойство, как и любое другое. Вы устанавливаете его в обработчикеDoWork
событий, как если бы вы устанавливали любое другое свойство, и вы получаете его в обработчикеRunWorkerCompleted
событий, как и любое другое свойство. Не пытайтесь усложнять это, когда это не так.5. @jmcilhinney Мне очень жаль, но я всегда использую двойной щелчок по объекту с помощью Visual Studio ao все эти частные вспомогательные, дескрипторы, результат e и другие вещи всегда генерируются автоматически, и я никогда не делаю это вручную. так что я действительно не знаю, как это сделать,