从BackgroundWorker中读取ListView

时间:2016-07-11 14:17:55

标签: vb.net multithreading listview backgroundworker

我尝试过一些搜索但是对于我的生活,我似乎无法找到答案,或建议的解决方案。这可能是我的理解,但希望问我自己的问题会给我一个有效的答案:o)

我有一个Windows窗体应用程序,它由一个项目ListView1

组成

此ListView通过拖放操作从文件中添加了项目,这是在主UI线程上完成的,没有后台工作者,它包含大约1500行。

我正在尝试让后台工作人员阅读这个ListView,但是我收到了一个交叉线程错误,因为ListView1没有在同一个线程上创建。

错误出现在最简单的代码片段上,但我似乎无法想到绕过它或实现调用等方法。

    For i = 0 To Me.ListView1.Items.Count - 1

        ValueStatement = ValueStatement & "(" & Me.ListView1.Items(i).SubItems(0).Text

        If i = Me.ListView1.Items.Count - 1 Or counter = 500 Then
            CommaTerminate = ";"
        Else
            CommaTerminate = ","
        End If


        For y = 0 To Me.ListView1.Columns.Count - 1
            ValueStatement = ValueStatement & "'" & Me.ListView1.Items(i).SubItems(y).Text & "'"
            If y = Me.ListView1.Columns.Count - 1 Then
                ValueStatement = ValueStatement & ")"
            Else
                ValueStatement = ValueStatement & ","
            End If

        Next
        ValueStatement = ValueStatement & CommaTerminate & vbNewLine


        If counter = 500 Then
            SQLStatement = "INSERT INTO RAW_CLI_DATA_" & GlobalVariables.CDR_Company & " VALUES " & vbNewLine & ValueStatement
            GenericDatabaseRequest(SQLStatement, "Loading RAW table with data..")
            counter = 0
            ValueStatement = ""
        End If

        counter = counter + 1
    Next

错误出现在ValueStatement = ValueStatement & "(" & Me.ListView1.Items(i).SubItems(0).Text

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

听起来你早就走错了路。对于数据库操作,ListView是极其错误的:

  • 所有内容都包含在String中,这意味着您将拥有将代码转换为其他类型的代码
  • 它不支持数据绑定,这意味着您必须手动创建行...
  • ...然后再迭代它们以取回数据。

DataGridViewDataTable会更简单:当用户将数据输入到控件中时,它将存储在表中并作为正确的类型。将DataTable设置为DatasourceDataGridView会为您创建显示(行和列)。

SQLite会花费一些时间来执行INSERT,但看起来你也花了很多时间迭代和连接SQL。无论如何,使用数据通常比用户的视图更好,因此提取并将数据传递给工作人员。

首先,将数据从ListView吸收到String()()容器中:

Dim data = lv.Items.
    Cast(Of ListViewItem).
    Select(Function(s) New String() {s.SubItems(0).Text,
                                     s.SubItems(1).Text,
                                     s.SubItems(2).Text}).
        ToArray()

然后将其传递给BackGroundWorker

bgw.RunWorkerAsync(data)

DoWork事件:

Private Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgw.DoWork

    ' unbox the data
    Dim dataToInsert = CType(e.Argument, String()())

    For n As Int32 = 0 To 2
        Console.WriteLine("[{0}], [{1}], [{2}]", dataToInsert(n)(0),
                          dataToInsert(n)(1),
                          dataToInsert(n)(2))
    Next

End Sub

结果:

  

[病人风暴],[Lorem ipsum dolor sit],[Swordfish]
  [Sour Priestess],[hendrerit nibh tempor],[Perch]
  [冰毒正义],[Interdum ex felis],[箭鱼]

它正确打印我放入LV的随机数据。

这将允许您处理ListView中的BackGroundWorker数据,但它不会真正节省任何时间,它只是保持UI解锁。真正的问题出在其他地方,可能是在DB操作中。