【问题标题】:Reading information from a ListView from another thread in Visual Basic从 Visual Basic 中的另一个线程从 ListView 读取信息
【发布时间】:2016-01-31 20:34:49
【问题描述】:

我在从 ListView 读取项目时遇到问题。 ListView 在主线程中,而我读出来的部分在另一个类和另一个线程中。我的代码如下:

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ltm As ListViewItem = New ListViewItem
        ltm.Text = "test1"
        ltm.SubItems.Add("test2")
        ltm.SubItems.Add("test3")
        Me.ListView2.Items.Add(ltm)
        Dim l As New test
        Dim x As New Threading.Thread(AddressOf l.readout)
    End Sub
End Class
Public Class test
    Public Sub readout()
        For Each i As ListViewItem In Form1.ListView2.Items
            Dim command As String = i.SubItems(0).Text
            Dim value As String = i.SubItems(1).Text
            Dim executeon As String = i.SubItems(2).Text
            MsgBox(command & vbCrLf & value & vbCrLf & executeon)
        Next
    End Sub
End Class

我听说过调用并找到了一些示例代码。我也尝试了以下方法:

 Dim selectedItem = CStr((New Func(Of String)(Function() Form1.ListView2.Items(0).Text)).Invoke)
        MsgBox(selectedItem)

但是,这也不起作用。没有错误消息,它只是不显示任何消息框。当我删除线程和同一类时,它工作得很好。有谁知道为什么它不起作用?

【问题讨论】:

  • 标准 VB.NET 错误,在工作线程中使用 Form1 会创建 Form1 类的 new 实例。除非您添加 Form1.ShowDialog(),否则您看不到它。如果您修复了该错误,那么您将获得 InvalidOperationException。不要在工作线程中弄乱 UI,给它一个 List(Of String) 来处理。

标签: .net multithreading listview invoke basic


【解决方案1】:

基本上,您不能从另一个线程触摸 UI 线程。很难准确说出您要做什么,但您当然可以检查您是否在非 UI 线程上并使用 InvokeRequired 和 BeginInvoke 在 UI 线程上继续执行。

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ltm As ListViewItem = New ListViewItem
        ltm.Text = "test1"
        ltm.SubItems.Add("test2")
        ltm.SubItems.Add("test3")
        Me.ListView2.Items.Add(ltm)
        Dim l As New test(ListView2)
        Dim x As New Threading.Thread(AddressOf l.readout)
        x.Start()
    End Sub
End Class

Public Class test

    Public Sub New(listview As ListView)
        _listview = listview
    End Sub

    Private _listview As ListView

    Public Sub readout()
        If _listview.InvokeRequired Then
            _listview.BeginInvoke(New Action(AddressOf readout))
        Else
            For Each i As ListViewItem In Form1.ListView2.Items
                Dim command As String = i.SubItems(0).Text
                Dim value As String = i.SubItems(1).Text
                Dim executeon As String = i.SubItems(2).Text
                MsgBox(command & vbCrLf & value & vbCrLf & executeon)
            Next
        End If
    End Sub
End Class

【讨论】:

  • 这对我帮助很大。谢谢你的回答,你救了我!
  • 我现在遇到了另一个问题。提供的代码是一个测试项目,因为实际的代码太大而无法显示。在测试项目中它工作得很好,但在实际项目中它给了我一个空引用错误。任何线索可能是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
相关资源
最近更新 更多