Vb.net 跨线程操作无效
我正在执行以下操作以尝试线程,但在Vb.net 跨线程操作无效,vb.net,Vb.net,我正在执行以下操作以尝试线程,但在txtBox.Text=DataGridView2.Rows.Item(iloop.Cells)(3.Value)行中出现“交叉线程”错误,任何人都可以指出错误,谢谢: Dim lm As New Thread(AddressOf load_movie) Dim lt As New Thread(AddressOf load_timings) lm.Start() lt.Start() Private Sub l
txtBox.Text=DataGridView2.Rows.Item(iloop.Cells)(3.Value)行中出现“交叉线程”错误,任何人都可以指出错误,谢谢:
Dim lm As New Thread(AddressOf load_movie)
Dim lt As New Thread(AddressOf load_timings)
lm.Start()
lt.Start()
Private Sub load_movie()
For iloop As Integer = 0 To DataGridView1.Rows.Count - 2
Dim Cstring As String = "txt_Movie_0" & iloop.ToString
For Each cCtrl As Control In Panel1.Controls
If TypeOf cCtrl Is TextBox Then
Dim txtBox As TextBox
txtBox = cCtrl
If txtBox.Name = Cstring Then
txtBox.Text = DataGridView1.Rows.Item(iloop).Cells(1).Value
End If
End If
Next
Next
End Sub
Private Sub load_timings()
For iloop As Integer = 0 To DataGridView2.Rows.Count - 2
For Each cCtrl As Control In Panel2.Controls
If TypeOf cCtrl Is TextBox Then
Dim txtBox As TextBox
txtBox = cCtrl
If (txtBox.Name.Substring(9, 6)) = (DataGridView2.Rows.Item(iloop).Cells(0).Value.substring(0, 6)) Then
txtBox.Text = DataGridView2.Rows.Item(iloop).Cells(3).Value 'This is the part that says "Cross-thread operation not valid: Control 'txt_Time_00_000' accessed from a thread other than the thread it was created on."
End If
End If
Next
Next
End Sub
在.Net代码中,从UI线程以外的任何地方访问UI元素都是不合法的。因此,当您尝试从后台线程使用DataGridView2
实例时,它会正确地抛出异常
为了读取或写入UI组件,您需要使用Invoke
或BeginInvoke
方法返回UI线程并进行更新。比如说
If TypeOf cCtrl Is TextBox Then
Dim txtBox As TextBox
txtBox = cCtrl
txtBox.Invoke(AddressOf UpdateTextBox, txtBox, iloop)
End If
Private Sub UpdateTextBox(txtBox as TextBox, iloop as Integer)
If (txtBox.Name.Substring(9, 6)) = (DataGridView2.Rows.Item(iloop).Cells(0).Value.substring(0, 6)) Then
txtBox.Text = DataGridView2.Rows.Item(iloop).Cells(3).Value 'This is the part that says "Cross-thread operation not valid: Control 'txt_Time_00_000' accessed from a thread other than the thread it was created on."
End If
End Sub
@JaredPar您已经有了基本的想法,但是代码本身无法编译(除非我遗漏了一些东西)。对于VB9或更低版本,您需要声明一个实际委托并调用:
''//The delegate is only needed for the VB 9 or less version
Private Delegate Sub UpdateTextBoxDelegate(ByVal txtBox As TextBox, ByVal value As String)
If TypeOf cCtrl Is TextBox Then
Dim txtBox As TextBox
txtBox = cCtrl
''//Perform validation logic here
If (txtBox.Name.Substring(9, 6)) = (DataGridView2.Rows.Item(iloop).Cells(0).Value.ToString().Substring(0, 6)) Then
''//Call the update method with our textbox and value
UpdateTextBox(txtBox, DataGridView2.Rows.Item(iloop).Cells(3).Value.ToString())
End If
End If
Private Sub UpdateTextBox(ByVal txtBox As TextBox, ByVal value As String)
''//Basically ask the textbox if we need to invoke
If txtBox.InvokeRequired Then
''//For VB 9 or less you need a delegate
txtBox.Invoke(New UpdateTextBoxDelegate(AddressOf UpdateTextBox), txtBox, value)
Else
txtBox.Text = value
End If
End Sub
对于VB 10,我们最终可以使用匿名sub,这样我们就可以完全摆脱委托:
If TypeOf cCtrl Is TextBox Then
Dim txtBox As TextBox
txtBox = cCtrl
''//Perform validation logic here
If (txtBox.Name.Substring(9, 6)) = (DataGridView2.Rows.Item(iloop).Cells(0).Value.ToString().Substring(0, 6)) Then
''//Call the update method with our textbox and value
UpdateTextBox(txtBox, DataGridView2.Rows.Item(iloop).Cells(3).Value.ToString())
End If
End If
Private Sub UpdateTextBox(ByVal txtBox As TextBox, ByVal value As String)
If txtBox.InvokeRequired Then
''//For VB 10 you can use an anonymous sub
txtBox.Invoke(Sub() UpdateTextBox(txtBox, value))
Else
txtBox.Text = value
End If
End Sub