Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 跨线程操作无效_Vb.net - Fatal编程技术网

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