从 BackgroundWorker 读取 ListView
Reading ListView from 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
感谢您的帮助!
听起来你很早就走错了路。 ListView
非常不适合数据库操作:
- 所有内容都包含在
String
中,这意味着您可以在某处使用代码将其转换为其他类型
- 它不支持数据绑定,这意味着您必须手动创建行...
- ...然后迭代它们以将数据捞回。
A DataGridView
和 DataTable
会更简单:当用户将数据输入控件时,它将存储在 table 中并作为正确的类型。将 DataTable
设置为 Datasource
,DataGridView
将为您创建显示(行和列)。
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
结果:
[Patient Tempest], [Lorem ipsum dolor sit], [Swordfish]
[Sour Priestess], [hendrerit nibh tempor], [Perch]
[Frozen Justice], [Interdum ex felis], [Swordfish]
它正确地打印了我放入 LV 的随机数据。
这将允许您处理 BackGroundWorker
中的 ListView
数据,但它不会真正节省任何时间,它只是保持 UI 解锁。真正的问题在别处,可能在数据库操作中。
我已经尝试进行一些搜索,但对于我来说,我似乎无法找到答案或建议的有效解决方案。这可能是我的理解,但希望问我自己的问题会给我一个有效的答案: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
感谢您的帮助!
听起来你很早就走错了路。 ListView
非常不适合数据库操作:
- 所有内容都包含在
String
中,这意味着您可以在某处使用代码将其转换为其他类型 - 它不支持数据绑定,这意味着您必须手动创建行...
- ...然后迭代它们以将数据捞回。
A DataGridView
和 DataTable
会更简单:当用户将数据输入控件时,它将存储在 table 中并作为正确的类型。将 DataTable
设置为 Datasource
,DataGridView
将为您创建显示(行和列)。
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
结果:
[Patient Tempest], [Lorem ipsum dolor sit], [Swordfish]
[Sour Priestess], [hendrerit nibh tempor], [Perch]
[Frozen Justice], [Interdum ex felis], [Swordfish]
它正确地打印了我放入 LV 的随机数据。
这将允许您处理 BackGroundWorker
中的 ListView
数据,但它不会真正节省任何时间,它只是保持 UI 解锁。真正的问题在别处,可能在数据库操作中。