如何在后台线程中迭代listview?

时间:2011-08-16 16:06:43

标签: vb.net multithreading listview

我有一个带有ListView的应用程序,我想循环遍历ListView中的每个项目。但我想在一个单独的线程中这样做。

这是一个非常简单的代码版本 - 但它的错误是相同的:

Private Sub StartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartToolStripMenuItem.Click
    pingThread = New Thread(AddressOf loopingRoutine)
    pingThread.Start()
End Sub

Public Sub loopingRoutine()
    For Each item As ListViewItem In ListView1.Items
        MsgBox(item.Text)
    Next
End Sub

导致以下错误:

  

跨线程操作无效:控制从其创建的线程以外的线程访问的“ListView1”。

为什么会这样?我在使用DataGridViews之前从未遇到过这个问题。

任何人都可以对此有所了解吗?

2 个答案:

答案 0 :(得分:2)

您无法从后台线程访问WinForms项目。它们与UI线程相关联。如果您过去能够以不同的类型执行此操作,那么您不幸的是它有效。

每当您想要使用特定控件时,您需要Invoke返回UI线程以访问其成员。在后台线程上执行诸如循环成员之类的操作是不可能的。

答案 1 :(得分:0)

有办法!希望我可以帮助其他人通过网络试图解决这个问题!

您需要使用委托线程调用项目并将其存储为列表。然后使用它...如果这是有道理的!

像这样:

    Private Sub StartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartToolStripMenuItem.Click
    pingThread = New Thread(AddressOf loopingRoutine)
    pingThread.Start()
End Sub

Public Sub loopingRoutine()
    Dim myList = DirectCast(Invoke(New GetListViewDelegate(AddressOf GetListViewItems)), List(Of String))
    For Each item As String In myList
        Dim array() As String = item.Split(";")
        MsgBox(array(0) & vbCrLf & array(1))
    Next
End Sub

Private Delegate Function GetListViewDelegate() As List(Of String)
Public Function GetListViewItems() As List(Of String)
    Return the list back to the delegate
    Dim pathList = New List(Of String)
    For Each item As ListViewItem In ListView1.Items
        pathList.Add(item.Text & ";" & item.Index)
    Next
    Return pathList
End Function

这可能不是最好的方法 - 但对于一个快速而肮脏的程序,它应该足够了:)