Vb.net net使用多线程遍历每个listviewitem
我对多线程非常陌生,但我正在尝试遍历每个listviewitem,其中子项1是“.”(quequed)。。我现在拥有的代码已经完成了前两个步骤,但是我如何才能让它继续下去?我目前正在运行两个线程 我制作了这个小示例应用程序来测试多线程,一旦掌握了它,我就可以将它应用到我的另一个应用程序中。。我非常希望它遍历状态为“.”的每个项目,然后它使时间增加到10000,直到它继续处理其他项目,直到没有剩余的项目。。任何帮助都将不胜感激Vb.net net使用多线程遍历每个listviewitem,vb.net,multithreading,listview,Vb.net,Multithreading,Listview,我对多线程非常陌生,但我正在尝试遍历每个listviewitem,其中子项1是“.”(quequed)。。我现在拥有的代码已经完成了前两个步骤,但是我如何才能让它继续下去?我目前正在运行两个线程 我制作了这个小示例应用程序来测试多线程,一旦掌握了它,我就可以将它应用到我的另一个应用程序中。。我非常希望它遍历状态为“.”的每个项目,然后它使时间增加到10000,直到它继续处理其他项目,直到没有剩余的项目。。任何帮助都将不胜感激 如果您使用的是.NET 4.5,我强烈建议您使用基于任务的方法。这种
如果您使用的是.NET 4.5,我强烈建议您使用基于任务的方法。这种方法使异步编程变得更加容易。我用
列表视图
重新创建了您描述的表单。我在柜台上加了第四栏
Public Class CParameters
Public Property LID As Integer
End Class
Private Async Function startThreadsAsync() As Task
'WARNING: Await does not create a new thread. Task.run does.
Await crunchThreadAsync(New CParameters() With {.LID = 0}) 'Create first task
Await crunchThreadAsync(New CParameters() With {.LID = 1}) 'Create second task
Await crunchThreadAsync(New CParameters() With {.LID = 2}) 'Create third task
End Function
Private Sub UpdateListItem(ByVal pid As Integer, ByVal Status As String, ByVal Time As String, ByVal Count As String)
If Not ListView1.InvokeRequired Then 'If on the main ui thread update
Dim lp As ListViewItem = ListView1.Items(pid)
lp.SubItems(0).Text = pid.ToString
lp.SubItems(1).Text = Status
lp.SubItems(2).Text = Time & "ms"
lp.SubItems(3).Text = Count
Else 'If not on the main ui thread invoke the listviews original thread(ui thread)
ListView1.BeginInvoke(Sub()
Dim lp As ListViewItem = ListView1.Items(pid)
lp.SubItems(0).Text = pid.ToString
lp.SubItems(1).Text = Status
lp.SubItems(2).Text = Time & "ms"
lp.SubItems(3).Text = Count
End Sub)
End If
End Sub
Private Async Function crunchThreadAsync(ByVal param As CParameters) As Task(Of Boolean)
'Setting start text
UpdateListItem(param.LID, "Running", "", "0")
Dim cnt As Integer = 0
Dim p As CParameters = param
Dim l As New Stopwatch() 'For displaying total time spent crunching
l.Start()
'We're not leaving the UI thread.'
'Create new thread for crunching
Dim result As Boolean = Await Task.Run(Function()
Do Until cnt = 10000
cnt = cnt + 1
If cnt Mod 1000 = 0 Then
UpdateListItem(param.LID, "", "", cnt.ToString)
End If
Loop
Return True
End Function)
'We're back in the UI thread again.
l.Stop()
UpdateListItem(param.LID, "Finished", l.ElapsedMilliseconds.ToString, cnt.ToString)
End Function
Private Async Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Text &= "Starting crunch." & Environment.NewLine
Await startThreadsAsync()
TextBox1.Text &= "Finished crunch." & Environment.NewLine
End Sub
我不会在每个计数器的每个刻度上更新ui线程,原因有几个:ui线程上的更新量会锁定ui。除了决定何时需要实际更新Ui之外,没有其他方法可以解决这个问题。在这种情况下,我每1000次做一次 表单仅在单个UI线程上运行。无论何时从非UI线程访问UI,都必须调用UI线程上的调用。这些调用将在UI线程上同步发生。因此,尝试多线程执行此操作是毫无意义的,这也是您不将数据存储在UI上的原因之一—只需使用UI输入和显示信息即可。表单后面应该有一个可以异步访问的数据结构。如果希望它做一件事直到完成,然后继续做下一件事,那么使用backgroundworker或线程是没有意义的。@Proputix我不希望它一次检查一项,在我的另一个应用程序上,我可以有数千项,如果每次都检查一次,需要几个小时。我需要多线程来同时检查多个项目。我制作这个示例应用程序只是为了弄清楚它是如何工作的,然后才能将它应用到我的其他应用程序中。
…它使时间增加到10000,直到它继续处理其他项目,直到没有剩下任何项目。
我不明白你的意思。这是一个例子,我目前正在做两个线程,只是作为一种检查之前,它应该继续与其他项目。嘿,伙计,刚刚有时间来测试这一点,因为我不能接受我目前的线程方法如何工作了。但是,您的代码似乎只检查前3项—我需要它工作,以便它检查所有项,直到它们全部检查完毕。我的另一个线程方法的问题是,它有时具有相同的索引,这导致它“错误地”更改剩余项的整数,因此它不会检查剩余的5%左右。你能更新你的代码以便它检查所有项目吗?非常感谢,谢谢。
Public Class CParameters
Public Property LID As Integer
End Class
Private Async Function startThreadsAsync() As Task
'WARNING: Await does not create a new thread. Task.run does.
Await crunchThreadAsync(New CParameters() With {.LID = 0}) 'Create first task
Await crunchThreadAsync(New CParameters() With {.LID = 1}) 'Create second task
Await crunchThreadAsync(New CParameters() With {.LID = 2}) 'Create third task
End Function
Private Sub UpdateListItem(ByVal pid As Integer, ByVal Status As String, ByVal Time As String, ByVal Count As String)
If Not ListView1.InvokeRequired Then 'If on the main ui thread update
Dim lp As ListViewItem = ListView1.Items(pid)
lp.SubItems(0).Text = pid.ToString
lp.SubItems(1).Text = Status
lp.SubItems(2).Text = Time & "ms"
lp.SubItems(3).Text = Count
Else 'If not on the main ui thread invoke the listviews original thread(ui thread)
ListView1.BeginInvoke(Sub()
Dim lp As ListViewItem = ListView1.Items(pid)
lp.SubItems(0).Text = pid.ToString
lp.SubItems(1).Text = Status
lp.SubItems(2).Text = Time & "ms"
lp.SubItems(3).Text = Count
End Sub)
End If
End Sub
Private Async Function crunchThreadAsync(ByVal param As CParameters) As Task(Of Boolean)
'Setting start text
UpdateListItem(param.LID, "Running", "", "0")
Dim cnt As Integer = 0
Dim p As CParameters = param
Dim l As New Stopwatch() 'For displaying total time spent crunching
l.Start()
'We're not leaving the UI thread.'
'Create new thread for crunching
Dim result As Boolean = Await Task.Run(Function()
Do Until cnt = 10000
cnt = cnt + 1
If cnt Mod 1000 = 0 Then
UpdateListItem(param.LID, "", "", cnt.ToString)
End If
Loop
Return True
End Function)
'We're back in the UI thread again.
l.Stop()
UpdateListItem(param.LID, "Finished", l.ElapsedMilliseconds.ToString, cnt.ToString)
End Function
Private Async Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Text &= "Starting crunch." & Environment.NewLine
Await startThreadsAsync()
TextBox1.Text &= "Finished crunch." & Environment.NewLine
End Sub