Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从vb.net中的多个线程更新listview_Vb.net_Multithreading_Listview - Fatal编程技术网

从vb.net中的多个线程更新listview

从vb.net中的多个线程更新listview,vb.net,multithreading,listview,Vb.net,Multithreading,Listview,我有一个程序,我想在其中使用多线程填充listview 但是我有一个问题,ui线程不能足够快地更新listview 当它运行checkWishList子项时,我得到listview1.Items.count=0 我尝试使用task.waitalltasks处理任务,我尝试使用task.Factory.continuewhalll处理任务,但这也在单独的线程中运行,因此我在尝试更新ui时出错 我唯一能做的就是 Do Until (tasks(0).Status = 5 And tasks(0).S

我有一个程序,我想在其中使用多线程填充listview

但是我有一个问题,ui线程不能足够快地更新listview

当它运行checkWishList子项时,我得到listview1.Items.count=0

我尝试使用task.waitalltasks处理任务,我尝试使用task.Factory.continuewhalll处理任务,但这也在单独的线程中运行,因此我在尝试更新ui时出错

我唯一能做的就是

Do Until (tasks(0).Status = 5 And tasks(0).Status = 5)
Application.DoEvents()
Loop
然而,这似乎是一个非常糟糕的解决方案,而不是一个真正的解决方案

所以我的问题是,是否有任何方法可以等待运行checkWishList,直到ui线程完成更新,或者我可以让Task.Factory.continue在ui线程中运行

或者我应该让线程填充listviewitems列表,而不是使用invoke调用uithread来添加项目,然后让listview连接到该数据源?这会让ui线程更新得更快吗

或者在列表上运行foreach并从ui线程将它们添加到listview

将有大约30-50条记录显示,但搜索这些记录需要时间,所以我希望在多个线程中完成

当然,我可以在添加listviewitem之前使用checkWishList DB查询并直接设置颜色,但由于我希望其他函数调用此sub,这也意味着我必须在多个位置使用相同的代码,使将来的更新/更改更成问题

我使用的是.NETFramework4.5

Private Delegate Sub ListViewAddItem_delegate(ByVal Col1 As String, ByVal Col2 As String, ByVal Col3 As String, ByVal Col4 As String, ByVal Col5 As String, ByVal col6 As String, ByVal col7 As String, ByVal col8 As String)
Private Sub ListViewAddItem(ByVal Col1 As String, ByVal Col2 As String, ByVal Col3 As String, ByVal Col4 As String, ByVal Col5 As String, ByVal col6 As String, ByVal col7 As String, ByVal col8 As String)
    If Me.listview1.InvokeRequired Then
        Dim d As New ListViewAddItem_delegate(AddressOf ListViewAddItem)
        Me.listview1.BeginInvoke(d, {Col1, Col2, Col3, Col4, Col5, col6, col7, col8})
    Else
        listview1.Items.Add(New ListViewItem(New String() {Col1, Col2, Col3, Col4, Col5, col6, col7, col8}))
    End If
End Sub


Private Sub search()
    listview1.Items.Clear()

    'Dim tasks = New Task(1) {}
    'For i As Integer = 0 To 1
            'if i = 0 then
                           'tasks(i) = Task.Run(AddressOf doSearch)
    'elseif i = 1 then
                            'tasks(i) = Task.Run(AddressOf doOtherSearch)
    'end if
    'Next
    'Task.Factory.ContinueWhenAll(tasks, Sub()
    '                                        Debug.Print("all threads done")
    '                                    End Sub)
    'Do Until (tasks(0).Status = 5 And tasks(0).Status = 5)
    '    Application.DoEvents()
    'Loop
    'Task.WaitAll(tasks)


    Parallel.For(0, 3, Sub(i)
    if i = 0 then
                           doSearch()
    elseif i = 1 then
                            doOtherSearch()
    end if
                               End Sub)
    checkWishlist()
End Sub


    Public Sub checkWishlist()
    For Each lvi As ListViewItem In listview1.Items
        thisSelectCommand.CommandText = "SELECT * FROM wishlist WHERE ID='" & lvi.SubItems(6).Text & "'"
        reader = thisSelectCommand.ExecuteReader
        If reader.HasRows = True Then
            lvi.ForeColor = Color.Red
        Else
            lvi.ForeColor = Color.Black
        End If
        reader.Close()
    Next
End Sub


public sub doSearch()
for i as integer = 0 to 100
ListViewAddItem("Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8")
next
End sub

public sub doOtherSearch()
for i as integer = 0 to 100
ListViewAddItem("Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8")
next
End sub

您可以使用后台工作人员,等待每个任务完成后再调用下一个任务,如下所示:

Private worker_1 As new BackgroundWorker()
Private worker_2 As new BackgroundWorker()

AddHandler worker_1.DoWork, AddressOf worker_1_DoWork
AddHandler worker_1.RunWorkerCompleted, AddressOf worker_1_RunWorkerCompleted
AddHandler worker_2.DoWork, AddressOf worker_2_DoWork
AddHandler worker_2.RunWorkerCompleted, AddressOf worker_2_RunWorkerCompleted

' call the first task
worker_1.RunWorkerAsync()

Public Sub worker_1_DoWork() 
 ' do something here
End Sub

Public Sub worker_1_RunWorkerCompleted
  ' call the next task only after the first task is complete
  worker_2.RunWorkerAsync()
End Sub

Public Sub worker_2_DoWork() 
 ' do something here
End Sub

Public Sub worker_2_RunWorkerCompleted
  ' call the next task
  ' and so on
End Sub

在单独的线程或任务中运行查询,然后将它们添加到主线程中的listview。您的意思是我应该在任务中运行she sql查询,并在使用ListViewAddItem或之前设置前景色?您可以使用同步锁,但这只会减慢您的速度。但它会起作用的。这基本上不是和Task.Factory.continuewhall一样吗?或者runWorkerCompleted是否在主线程ui线程中运行?问题是,我希望worker 1和worker 2并行运行,然后再运行checkWishlist。所以parallel for循环将完成我正在寻找的任务,因为它在继续之前会等待所有线程使用芬兰语。但是,如果我正确理解委托/调用子队列,ui将更新,因此在ui有时间将所有项目添加到listview之前,checkWishlist将被取消。如果主线程中运行的两个项目之间存在竞争条件,则需要等待其中一个项目完成,以说明所有情况。如果这意味着把它们放在不同的线程中,那么也许你应该考虑一下。要回答您的问题,是的,runWorkerCompleted在主线程中运行。