Link to home
Start Free TrialLog in
Avatar of cmdolcet
cmdolcetFlag for United States of America

asked on

How to allow a cross-thread operation to be valid

I am getting an invalidOperationExcception was manhandled error saying that there a cross-thread operation not valid on the following line  CType(newGraphics.readingLabelArrayList(intloop), Label).Text = tempArrayCOM1(1)



Here's the whole code:

  Public Sub DataReceivedEventHandler(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
        'Try
        'Dim sp As SerialPort
        sp = CType(sender, SerialPort)
        BoolMultipleReadings1 = True
        Threading.Thread.Sleep(300)
        buffer1 = String.Empty

        Dim strData As String = sp.ReadExisting()
        buffer1 = buffer1 & strData
        If System.Text.RegularExpressions.Regex.IsMatch(buffer1, "([\r]).*?\1") Then
            strData = String.Empty
            buffer1 = String.Empty
            sp.DiscardOutBuffer()
            sp.DiscardInBuffer()
            Exit Sub
        End If

        Dim index1 As Integer = buffer1.IndexOf(EOM)
        'Dim index2 As Integer = buffer2.IndexOf(EOM)
        While index1 <> -1
            If buffer1.Length > 0 Then
                Value1 = buffer1.Substring(0, index1)
                buffer1 = buffer1.Substring(index1 + EOM.Length)
                index1 = buffer1.IndexOf(EOM)
            End If
        End While

        'Do Until COM1isBusy = True Or Value2 = String.Empty
        'Loop


        'Dim tempArrayCOM1() As String
        Dim intloop, intloop2 As Integer
        If Value1.Length > 0 Then

            ACK_Received = False
            For intloop = 0 To pFile.Gages.Count - 1
                If pFile.Gages(intloop).GageType = "G-300 Flush" Or pFile.Gages(intloop).GageType = "G-300 Gap" Then
                    WirelessG300_Type = True
                ElseIf pFile.Gages(intloop).GageType = "G-241 Flush" Or pFile.Gages(intloop).GageType = "G-241 Gap" Then
                    WirelessG241_Type = True
                ElseIf pFile.Gages(intloop).GageType = "G-WHIZ" Or pFile.Gages(intloop).GageType = "G-WHIZ1" Or pFile.Gages(intloop).GageType = "G-WHIZ2" Then
                    WirelessGWHIZ_Type = True
                End If
            Next

            If WirelessG241_Type = True And WirelessG300_Type = True Then
                Mulitple_WirelessGage_In_Program = True
            Else
                Single_WirelessGage_In_Program = True
            End If

            WirelessGageIDG241.Clear()
            Value1 = Value1.Replace(vbCrLf, vbTab).Replace(Chr(26), "").Replace(Chr(12), "").Replace(Chr(13), "")
            EntryCounter = EntryCounter + 1
            'System.Threading.Thread.Sleep(500)
            tempArrayCOM1 = Split(Value1, ",")
            ' tempWirelessIDArray = Split(pFile.Gages(intloop).Description, ",")
            If tempArrayCOM1.Length = 3 And tempArrayCOM1(0).Length = 16 Then
                WirelessGageIDG300.Add(tempArrayCOM1(2))
                WirelessPointNameG300.Add(tempArrayCOM1(0))
                muxClass.GetG300Data(tempArrayCOM1)
                EnteredACK = True
                'AddHandler dataBackgroundWorker.RunWorkerCompleted, AddressOf WirelessG300Workcomplete
                Exit Sub
            ElseIf tempArrayCOM1.Length = 5 And tempArrayCOM1(0).Length = 16 Then
                WirelessGageIDG241.Add(tempArrayCOM1(4))
                WirelessPointFlush.Add(tempArrayCOM1(0))
                WirelessPointGap.Add(tempArrayCOM1(2))
                muxClass.GetG241Data(tempArrayCOM1)
                EnteredACK = True
                ' AddHandler dataBackgroundWorker.RunWorkerCompleted, AddressOf WirelessG241Workcomplete
                'Exit Sub
            ElseIf tempArrayCOM1.Length = 3 And tempArrayCOM1(0).Length <= 4 Or tempArrayCOM1.Length = 3 And tempArrayCOM1(0).Length = 5 Then
                strData = String.Empty
                buffer1 = String.Empty
                tempArrayCOM1(0) = tempArrayCOM1(0).Replace("<", "")
                WirelessGageIDGWHIZ.Add(tempArrayCOM1(2))
                WirelessPointNameGWHIZ.Add(tempArrayCOM1(0))
                muxClass.GetGWHIZData(tempArrayCOM1)
                GWHIZDataReceivedEvent1 = True
                GWHIZDataReceivedEvent2 = False
                ' AddHandler dataBackgroundWorker.RunWorkerCompleted, AddressOf WirelessG241Workcomplete
                ' AddHandler dataBackgroundWorker.RunWorkerCompleted, AddressOf WirelessGWHIZInlineWorkcomplete
                Dim passed As Boolean
                Dim gage As PartfileLibrary.Gages
                Dim resample As Boolean = True
                Dim tempArray() As String
                Dim serialresponse1 As String = String.Empty
                For intloop = 0 To newGraphics.charLabelArrayList.Count - 1
                    For Each gage In pFile.Gages
                        If muxClass.DSIValues.Count = 1 Then
                            If WirelessPointNameGWHIZ(0).Trim.ToString = CType(newGraphics.charLabelArrayList(intloop), Label).Text Then 'Gets the value to place in the textbox
                                CType(newGraphics.readingLabelArrayList(intloop), Label).Text = tempArrayCOM1(1) 'Format(muxClass.DSIValues(0) + gage.Offset, howToDiplayDecimalPlaces)
                                CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor = ChangeReadingColor(muxClass.DSIValues(0), CType(newGraphics.readingLabelArrayList(intloop), Label).Name)
                                newGraphics.readingLabelArrayList(intloop).font = New Font(CType(newGraphics.readingLabelArrayList(intloop), Label).Font, FontStyle.Bold)
                                If CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.Tomato) Or CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.DeepSkyBlue) Then
                                    passed = False
                                Else
                                    passed = True
                                End If
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) * -1 + gage.Offset, passed, intCurrentPartNumber)
                                Else
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) + gage.Offset, passed, intCurrentPartNumber)
                                End If
                                calcOperations.PerformCalculations(tmpSavedInfo, newGraphics.readingLabelArrayList, pFile, intCurrentPartNumber, boolMinMaxStartButtonBeenPressed)
                                resample = False
                                boolDSISampledGWHIZ = True
                                If boolDSISampledGWHIZ = True And GWHIZDataReceivedEvent1 = True Then
                                    If boolDSISampledGWHIZ = True Then
                                        System.Threading.Thread.Sleep(300)
                                        CType(serialPortsArrList(0), IO.Ports.SerialPort).Write("<@:L" & WirelessGageIDGWHIZ(0) & "07<ACKTP>")
                                        System.Threading.Thread.Sleep(300)
                                        G300CurrentSerial = CType(serialPortsArrList(0), IO.Ports.SerialPort).PortName
                                        G300ReadingACKSent = True
                                        boolDSISampledGWHIZ = False
                                    End If

                                ElseIf boolDSISampledGWHIZ = True And GWHIZDataReceivedEvent2 = True Then
                                    CType(serialPortsArrList(1), IO.Ports.SerialPort).Write("<@:L" & WirelessGageIDGWHIZ(0) & "07<ACKTP>")
                                    System.Threading.Thread.Sleep(300)
                                    G300CurrentSerial = CType(serialPortsArrList(1), IO.Ports.SerialPort).PortName
                                    System.Threading.Thread.Sleep(300)
                                    G300ReadingACKSent = True
                                    boolDSISampledGWHIZ = False
                                End If
                                muxClass.DSIValues.Clear()
                                WirelessPointNameGWHIZ.Clear()
                                WirelessGageIDGWHIZ.Clear()
                                mainFormStatusStripLabel.BackColor = System.Drawing.SystemColors.Control
                                mainFormStatusStripLabel.Font = New System.Drawing.Font("Tahoma", 8.25)
                                MoveToNextReadingWithSameGageType()
                                GetFinalQualityDSI()
                            Else

                            End If
                        ElseIf muxClass.DSIValues.Count = 2 Then
                            'G-WHIZ POINT A
                            If WirelessPointNameGWHIZ(0).Trim.ToString = gage.Characteristic And WirelessPointNameGWHIZ(0).Trim.ToString = CType(newGraphics.charLabelArrayList(intloop), Label).Text Then 'gage.Characteristic Then
                                'Gets the value to place in the textbox
                                CType(newGraphics.readingLabelArrayList(intloop), Label).Text = Format(muxClass.DSIValues(0) + gage.Offset, howToDiplayDecimalPlaces)

                                'Inverts the reading
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    CType(newGraphics.readingLabelArrayList(intloop), Label).Text = Format(CSng(CType(newGraphics.readingLabelArrayList(intloop), Label).Text) * -1, howToDiplayDecimalPlaces)
                                End If

                                CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor = ChangeReadingColor(muxClass.DSIValues(0), CType(newGraphics.readingLabelArrayList(intloop), Label).Name)
                                newGraphics.readingLabelArrayList(intloop).font = New Font(CType(newGraphics.readingLabelArrayList(intloop), Label).Font, FontStyle.Bold)
                                calcOperations.PerformCalculations(tmpSavedInfo, newGraphics.readingLabelArrayList, pFile, intCurrentPartNumber, boolMinMaxStartButtonBeenPressed)
                                Threading.Thread.Sleep(500)
                                If CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.Tomato) Or CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.DeepSkyBlue) Then
                                    passed = False
                                Else
                                    passed = True
                                End If
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) * -1 + gage.Offset, passed, intCurrentPartNumber)
                                Else
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) + gage.Offset, passed, intCurrentPartNumber)
                                End If
                            Else
                            End If
                            'G-WHIZ POINT B
                            If WirelessPointNameGWHIZ(0).Trim.ToString = gage.Characteristic And WirelessPointNameGWHIZ(0).Trim.ToString = CType(newGraphics.charLabelArrayList(intloop), Label).Text Then 'gage.Characteristic Then
                                'Gets the value to place in the textbox
                                intloop = intloop + 1
                                CType(newGraphics.readingLabelArrayList(intloop), Label).Text = Format(muxClass.DSIValues(1) + gage.Offset, howToDiplayDecimalPlaces)

                                'Inverts the reading
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    CType(newGraphics.readingLabelArrayList(intloop), Label).Text = Format(CSng(CType(newGraphics.readingLabelArrayList(intloop), Label).Text) * -1, howToDiplayDecimalPlaces)
                                End If

                                'Gap Reading
                                CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor = ChangeReadingColor(muxClass.DSIValues(1), CType(newGraphics.readingLabelArrayList(intloop), Label).Name)
                                newGraphics.readingLabelArrayList(intloop).font = New Font(CType(newGraphics.readingLabelArrayList(intloop), Label).Font, FontStyle.Bold)
                                calcOperations.PerformCalculations(tmpSavedInfo, newGraphics.readingLabelArrayList, pFile, intCurrentPartNumber, boolMinMaxStartButtonBeenPressed)
                                resample = False
                                If CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.Tomato) Or CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.DeepSkyBlue) Then
                                    passed = False
                                Else
                                    passed = True
                                End If
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(1) * -1 + gage.Offset, passed, intCurrentPartNumber)
                                Else
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(1) + gage.Offset, passed, intCurrentPartNumber)
                                End If
                                resample = False
                                boolDSISampledGWHIZ = True
                                If boolDSISampledGWHIZ = True And GWHIZDataReceivedEvent1 = True Then
                                    If boolDSISampledGWHIZ = True Then
                                        CType(serialPortsArrList(0), IO.Ports.SerialPort).Write("<@:L" & WirelessGageIDGWHIZ(0) & "07<ACKTP>")
                                        System.Threading.Thread.Sleep(300)
                                        G300CurrentSerial = CType(serialPortsArrList(0), IO.Ports.SerialPort).PortName
                                        System.Threading.Thread.Sleep(300)
                                        G300ReadingACKSent = True
                                        boolDSISampledGWHIZ = False
                                    End If

                                ElseIf boolDSISampledGWHIZ = True And GWHIZDataReceivedEvent2 = True Then
                                    CType(serialPortsArrList(1), IO.Ports.SerialPort).Write("<@:L" & WirelessGageIDGWHIZ(0) & "07<ACKTP>")
                                    System.Threading.Thread.Sleep(300)
                                    G300CurrentSerial = CType(serialPortsArrList(1), IO.Ports.SerialPort).PortName
                                    System.Threading.Thread.Sleep(300)
                                    G300ReadingACKSent = True
                                    boolDSISampledGWHIZ = False
                                End If
                                muxClass.DSIValues.Clear()
                                WirelessPointNameGWHIZ.Clear()
                                WirelessGageIDGWHIZ.Clear()
                                mainFormStatusStripLabel.BackColor = System.Drawing.SystemColors.Control
                                mainFormStatusStripLabel.Font = New System.Drawing.Font("Tahoma", 8.25)
                                MoveToNextReadingWithSameGageType()
                                GetFinalQualityDSI()
                                Exit Sub
                            Else
                            End If
                        Else
                        End If
                    Next
                Next
                EnteredACK = True
           ElseIf tempArrayCOM1.Length = 4 And tempArrayCOM1(0).Length <= 4 Or tempArrayCOM1.Length = 4 And tempArrayCOM1(0).Length = 5 Then
                tempArrayCOM1(0) = tempArrayCOM1(0).Replace("<", "")
                WirelessGageIDGWHIZ.Add(tempArrayCOM1(3))
                WirelessPointNameGWHIZ.Add(tempArrayCOM1(0))
                muxClass.GetGWHIZData(tempArrayCOM1)
                GWHIZDataReceivedEvent1 = True
                GWHIZDataReceivedEvent2 = False
                EnteredACK = True
            ElseIf tempArrayCOM1.Length = 2 And Not tempArrayCOM1(0) = "G300-DONE" And Not tempArrayCOM1(0) = "G241-DONE" Then
                'Do nothing
                If tempArrayCOM1(0) = "ack" Then
                    G241ReadingACKSent = False
                    G300ReadingACKSent = False
                    WirelessGageIDG241.Clear()
                    Value1 = String.Empty
                End If
            ElseIf tempArrayCOM1(0) = "G300-DONE" Then
                WirelessGageIDG300.Add(tempArrayCOM1(1))
                muxClass.G300_Push_Button_Status_Response = True
                muxClass.GetG300Data(tempArrayCOM1)
                If Single_WirelessGage_In_Program = True Then
                    MoveToNextReadingWithSameGageType()
                    'Exit Sub
                ElseIf Mulitple_WirelessGage_In_Program = True Then
                    If muxClass.G300_Push_Button_Status_Response = True And muxClass.G241_Push_Button_Status_Response = True Then
                        MoveToNextReadingWithSameGageType()
                        'Exit Sub
                    End If
                End If
            ElseIf tempArrayCOM1(0) = "G241-DONE" Then
                WirelessGageIDG241.Add(tempArrayCOM1(1))
                muxClass.G241_Push_Button_Status_Response = True
                muxClass.GetG241Data(tempArrayCOM1)
                If Single_WirelessGage_In_Program = True Then
                    MoveToNextReadingWithSameGageType()
                    'Exit Sub
                ElseIf Mulitple_WirelessGage_In_Program = True Then
                    If muxClass.G300_Push_Button_Status_Response = True And muxClass.G241_Push_Button_Status_Response = True Then
                        MoveToNextReadingWithSameGageType()
                        'Exit Sub
                    End If
                End If
            End If
        Else
        End If
        strData = String.Empty
        'Catch ex As Exception
        'End Try
    End Sub

Open in new window

Avatar of kaufmed
kaufmed
Flag of United States of America image

You need to invoke access to UI controls when you are trying to update said controls from a thread other than the UI thread (i.e. the main application thread). Invoke more or less looks like this:

Function SetMyLabelText(ByVal text As String)
    If myLabel.InvokeRequired Then
        Me.myLabel.Invoke(New Action(Of String)(AddressOf SetMyLabelText), text)
    Else
        Me.myLabel.Text = text.ToString()
    End If
End Function

Open in new window


Then, instead of assigning directly to the control, you go through the new method:

e.g.

SetMyLabelText("Hello World!")

Open in new window


More information on invoke and InvokeRequired:  http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired(v=vs.90).ASPX
Avatar of cmdolcet

ASKER

OK, I think I understand however how do I make that call in my code?
Anywhere where you have code that manipulates a UI element (e.g. TextBox, Label, Button, etc.), you will need invoke. Examples include lines 95 - 98. So create a new function for each control that needs to be accessed, and then replace any explicit writes of control properties with calls to invoke function.

The function shown above is flexible enough to be used either on the main thread or a secondary thread--due to the InvokeRequired check.

I cannot immediately recall, but I believe you will also need invoke to read a property's value as well.

e.g.

Function GetMyLabelText()
    If myLabel.InvokeRequired Then
        Me.myLabel.Invoke(New Action(Of String)(AddressOf GetMyLabelText))
    Else
        Return Me.myLabel.Text
    End If
End Function

Open in new window


You can try running without the above, and if you encounter any exceptions while trying to read UI control property values, then add in something similar.
Here's a slightly more flexible function definition:

SetControlText(ByVal control As Control, ByVal text As String)
    If control.InvokeRequired Then
        control.Invoke(New Action(Of Control, String)(AddressOf SetControlText), control, text)
    Else
        control.Text = text
    End If
End Sub

Open in new window


With this version, you shouldn't have to write multiple functions. You simply need to call the function and pass the target control in as an argument:

e.g.

SetControlText(Me.myLabel, "Hello")

Open in new window


The rest of my previous post still applies.
OK you really lost me...what do I need to call and not call?
1) Add in the new function that I showed you above  (http:#a39681287)
a) This function only handles text. If you assign to other properties (e.g. Font, BackgroundColor, etc.), then you will need a new function for each new property
2) Go through your DataReceivedEventHandler function, line by line
a) Wherever you have a line that assigns to the Text property of a UI control, change that line into a call to the new function, passing in that particular UI control as the first parameter to the new function

b) If you create a new function for some other property as mentioned in 1a, then wherever you have a line that assigns to that property, replace that line with a call to the new function, passing in the control as the first parameter to the new function
Ok thank you for clearing that up, when I import the code you outlined above I get an error on the (New Action(of Control, string) stating there are too many arguments to the system.action(of T)
Did you copy it exactly? Note the two sets of parentheses:

New Action(Of Control, String)(AddressOf SetControlText)

Open in new window


The first set is the type arguments to the generic. The second set is the parameters to be passed to that class' constructor.
Yes I copied it from your example you referenced.
I'm not certain then. That code is working on my system:

User generated image
I am using VB 2005 which version are you in 2010?
Here's a screen shot
Image.png
Ah, that could be the issue. I cannot remember when the generic versions of Action were introduced. Let me see if I can rework the solution.
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OK, cool that looks like it will work no errors on the delegate.

Hw do I call the setControl Text with using my old code that is this way?

CType(newGraphics.readingLabelArrayList(intloop), Label).Text = tempArrayCOM1(1)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OK, would I do the same changes for every reference of the readingLabelArrayList?

So backcolor, Font,

 CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor = ChangeReadingColor(muxClass.DSIValues(0), CType(newGraphics.readingLabelArrayList(intloop), Label).Name)
                                newGraphics.readingLabelArrayList(intloop).font = New Font(CType(newGraphics.readingLabelArrayList(intloop), Label).Font, FontStyle.Bold)
                                If CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.Tomato) Or CType(newGraphics.readingLabelArrayList(intloop), Label).BackColor.Equals(Color.DeepSkyBlue) Then
                                    passed = False
                                Else
                                    passed = True
                                End If
                                If InvertSignOfReading(CType(newGraphics.charLabelArrayList(intloop), Label).Text) And Not CType(newGraphics.readingLabelArrayList(intloop), Label).Text = "4096" Then
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) * -1 + gage.Offset, passed, intCurrentPartNumber)
                                Else
                                    tmpSavedInfo.UpdateSavedData(pFile, WirelessPointNameGWHIZ(0).Trim.ToString, False, muxClass.DSIValues(0) + gage.Offset, passed, intCurrentPartNumber)
                                End If

                                calcOperations.PerformCalculations(tmpSavedInfo, newGraphics.readingLabelArrayList, pFile, intCurrentPartNumber, boolMinMaxStartButtonBeenPressed)
You'd need a similar set of delegates/subs for those properties, such as:
    Private SetCtrlBackColorDlg As New SetControlBackColorDlg(AddressOf SetControlBackColor)
    Private Delegate Sub SetControlBackColorDlg(ByVal control As Control, ByVal clr As Color)

    Public Sub SetControlBackColor(ByVal control As Control, ByVal clr As Color)
        If control.InvokeRequired Then
            control.Invoke(SetCtrlBackColorDlg, control, clr)
        Else
            control.BackColor = clr
        End If
    End Sub

Open in new window

hi.. this is your solution

1- Create your thread:
Private Strt As System.Threading.Thread  

2- Start your thread wherever you want:
Strt = New System.Threading.Thread(AddressOf MyThread1)
  Strt.Start()

3- Add the thread sub (MyThread1) and put whatever you want and remember that the lines which access a control from this thread will be separated to into another sub (the Delegate sub)
Sub MyThread1
       ' Working code
       ' Working code
       ' Working code
       ' Working code
       ' Working code
       ' Working code

       AccessControl()

End Sub

From the previous code you will notice 2 things:
1st: AccessControl the sub which will be delegated.
2nd: ' Working code - which doesn't need a delegate to get it work. In other mean, it doesn't show up the error message you receive.

4- and finally, add the delegated sub:
Private Sub AccessControl()
        If Me.InvokeRequired Then
            Me.Invoke(New MethodInvoker(AddressOf AccessControl))
        Else
    ' Code wasn't working in the threading sub
    ' Code wasn't working in the threading sub
    ' Code wasn't working in the threading sub
    ' Code wasn't working in the threading sub
    ' Code wasn't working in the threading sub
            Button2.Visible = True
            Button3.Visible = True
            Opacity = 1
            ShowInTaskbar = True
        End If
    End Sub

From the previous code you will notice that all the codes which wasn't working in the threading sub will be added after "Else" line.
examples for some codes which needs to be delegated:
(Control).Visible
Me.Opacity
Me.ShowInTaskbar
Idle_Mind, how can I call my delegates for the backcolor and font again?