VB.net Поток безопасный метод, чтобы добавить подпункт списка? - PullRequest
0 голосов
/ 21 февраля 2011

Я пытаюсь добавить подэлемент в просмотр списка потокобезопасным способом.

В однопоточном приложении это работает так:

    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, но все примеры, которые я видел, включают обновление свойства text объекта, и я не могу понять, как применить концепцию для фактического добавления подэлемента в просмотр списка. .

Любая помощь очень ценится.

Ответы [ 4 ]

1 голос
/ 09 января 2016

Потокобезопасный упрощенный способ добавления нового 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
1 голос
/ 26 мая 2012

Вот пример, который я использую снова и снова для своих собственных нужд. Он поддерживает передачу переменных. Мой список в этом примере имеет 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)

Я добавил материал "dim xxx as string", чтобы показать, что PR группы имен были строками при вызове ListViewAddItem ()

Я заметил, что ответ не был выбран. Сделайте нам одолжение и выберите один! Спасибо!

0 голосов
/ 21 февраля 2011

Простой пример

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
0 голосов
/ 21 февраля 2011
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
...