【问题标题】:VB.net Thread safe method to add a listview subitem?VB.net 线程安全方法添加列表视图子项?
【发布时间】:2016-01-09 19:57:57
【问题描述】:

我正在尝试以线程安全的方式将子项添加到列表视图。

在单线程应用程序中,它的工作方式如下:

    For i As Integer = 0 to lvMembers.Items.Count - 1
    Dim lv As ListViewItem = lvMembers.Items(i)
    Dim str As String = lv.Text.ToString
    If str.Contains("value")
    lv.SubItems.Add("OK")
    lv.SubItems(0).ForeColor = Color.Green

    Else
    lv.SubItems.Add("FAILED")
    lv.SubItems(0).ForeColor = Color.Red

    End If
    Next

但是,如果在另一个线程中运行,则会导致跨线程错误。

我查看了使用 Invoke 的委托子示例,但我所看到的所有示例都涉及更新对象的文本属性,我无法理解如何应用该概念以实际将子项添加到列表视图.

非常感谢任何帮助。

【问题讨论】:

  • 我没有看到问题。你能发布你如何使用委托吗?
  • 我的问题是,如果我在主 UI 线程以外的任何地方运行它,它会引发跨线程异常。如果在第二行失败,那么我想我将不得不改变我的整个方法,但不知道从哪里开始。

标签: vb.net listview thread-safety


【解决方案1】:

将新 ListViewItem 添加到 ListView 的线程安全简化方法:

Private Sub AddListViewItem(ByVal name As String, ByVal subitem1 As String, ByVal subitem2 As String)
    ListView1.BeginInvoke(Sub()
                              Dim lvi As New ListViewItem(name)
                              lvi.SubItems.Add(subitem1)
                              lvi.SubItems.Add(subitem2)
                              ListView1.Items.AddRange(New ListViewItem() {lvi})
                          End Sub)
End Sub

【讨论】:

    【解决方案2】:

    这是一个我自己反复使用的例子。它支持传递变量。我在这个例子中的列表视图有 1 个项目和 2 个子项目(站点、组、pagerank),所以修改它以供您自己使用:

    委托人:

    Private Delegate Sub ListViewAddItem_delegate(ByVal name As String, ByVal group As String, ByVal pagerank As String)
    Private Sub ListViewAddItem(ByVal name As String, ByVal group As String, ByVal pagerank As String)
        If Me.ListView1.InvokeRequired Then
            Dim d As New ListViewAddItem_delegate(AddressOf ListViewAddItem)
            Me.ListView1.BeginInvoke(d, {name, group, pagerank})
        Else
            Dim lvi As New ListViewItem(name)
            lvi.SubItems.Add(group)
            lvi.SubItems.Add(pagerank)
            ListView1.Items.AddRange(New ListViewItem() {lvi})
            ListView1.Update()
        End If
    End Sub
    

    如何称呼它:

    Dim Name as string = "Test"
    Dim Group As String = "TestGroup"
    Dim PR As String = "10"
    ListViewAddItem(Name, Group, PR)
    

    我在调用 ListViewAddItem() 时添加了“dim xxx as string”只是为了表明 Name Group PR 是字符串

    我注意到没有选择任何答案。帮我们大家一个忙,然后选择一个!谢谢!

    【讨论】:

      【解决方案3】:

      一个简单的例子

      Public Class Form1
      
          Private Sub Form1_Load(ByVal sender As System.Object, _
                                 ByVal e As System.EventArgs) Handles MyBase.Load
      
              'sample data for the ListView
              Dim ipsumA() As String = New String() {"Lorem", "ipsum", "dolor", "sit", _
                                                     "amet", "consectetur", "adipisicing", _
                                                     "elit", "sed", "do", "eiusmod", _
                                                     "tempor", "incididunt", "ut", "labore", _
                                                     "et", "dolore", "magna", "aliqua", "Ut", _
                                                     "enim", "ad", "minim", "veniam", "quis", _
                                                     "nostrud", "exercitation", "ullamco", _
                                                     "laboris", "nisi", "ut", "aliquip", "ex", _
                                                     "ea", "commodo", "consequat", "Duis", "aute", _
                                                     "irure", "dolor", "in", "reprehenderit", "in", _
                                                     "voluptate", "velit", "esse", "cillum", "dolore", _
                                                     "eu", "fugiat", "nulla", "pariatur", "Excepteur", _
                                                     "sint", "occaecat", "cupidatat", "non", "proident", _
                                                     "sunt", "in", "culpa", "qui", "officia", "deserunt", _
                                                     "mollit", "anim", "id", "est", "laborum"}
      
              Dim lvi As New List(Of ListViewItem)
      
              For Each s As String In ipsumA
                  Dim nLVI As New ListViewItem(s)
                  lvi.Add(nLVI)
              Next
      
              ListView1.Items.AddRange(lvi.ToArray)
      
              'colorize from another thread
              Dim t As New Threading.Thread(AddressOf thrd)
              t.Start()
      
          End Sub
      
          Private Sub thrd()
              If ListView1.InvokeRequired Then
                  ListView1.BeginInvoke(New MethodInvoker(AddressOf thrd))
              Else
                  For i As Integer = 0 To ListView1.Items.Count - 1
                      Dim lv As ListViewItem = ListView1.Items(i)
                      Dim str As String = lv.Text.ToString
                      If str.ToLower.Contains("ut") Then
                          lv.SubItems.Add("OK")
                          lv.SubItems(0).ForeColor = Color.Green
      
                      Else
                          lv.SubItems.Add("FAILED")
                          lv.SubItems(0).ForeColor = Color.Red
                      End If
                  Next
              End If
          End Sub
      End Class
      

      【讨论】:

        【解决方案4】:
        Private delegate sub deladdtolist
        
        Private sub addtolist
          If InvokeRequired Then
            del.Invoke( new deladdtolist(AddressOf addtolist))
          else
            For i As Integer = 0 to lvMembers.Items.Count - 1
            Dim lv As ListViewItem = lvMembers.Items(i)
            Dim str As String = lv.Text.ToString
            If str.Contains("value")
            lv.SubItems.Add("OK")
            lv.SubItems(0).ForeColor = Color.Green
        
            Else
            lv.SubItems.Add("FAILED")
            lv.SubItems(0).ForeColor = Color.Red
        
            End If
            Next
          End If 
        End Sub
        

        【讨论】:

          猜你喜欢
          • 2017-04-08
          • 1970-01-01
          • 2017-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多