Cross-thread operation not valid

前端 未结 2 1847
花落未央
花落未央 2020-12-21 15:51

I was doing the following to try out threadings but get the \'Cross-Threading\' error in the line txtBox.Text = DataGridView2.Rows.Item(iloop).Cells(3).Value, a

相关标签:
2条回答
  • 2020-12-21 16:23

    It's not legal to access a UI element from anything other than UI thread in .Net code. Hence when you try and use the DataGridView2 instance from a background thread it rightfully throws an exception.

    In order to read or write to a UI component you need to use Invoke or BeginInvoke method to get back on the UI thread and make the update. For example

    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
    
    0 讨论(0)
  • 2020-12-21 16:37

    @JaredPar you have the basic idea but that code itself won't compile (unless I'm missing something). For VB9 or less you need to declare an actual delegate and invoke that:

        ''//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
    

    For VB 10 we can finally use anonymous subs so we can completely get rid of the delegate:

        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
    
    0 讨论(0)
提交回复
热议问题