I\'m having an issue with multithreading pings that are hanging up my main thread. When debugging the issue, I notice that while the main thread is hung up, it is starting each
The problem here is that you invoke the same methods once again, which are supposed to be run in threads. This causes the ping request to be sent yet another time, but this time the code runs on the UI thread (hence why it freezes). You should make sure to only invoke the code that updates the UI.
This is optional, but I recommend you to use an extension method to do the invocation check for you since it will improve readability but also decrease the amount of code you have to write:
Imports System.Runtime.CompilerServices
Public Module Extensions
<Extension()> _
Public Sub InvokeIfRequired(ByVal Control As Control, ByVal Method As [Delegate], ByVal ParamArray Parameters As Object())
If Parameters Is Nothing OrElse _
Parameters.Length = 0 Then Parameters = Nothing 'If Parameters is null or has a length of zero then no parameters should be passed.
If Control.InvokeRequired = True Then
Control.Invoke(Method, Parameters)
Else
Method.DynamicInvoke(Parameters)
End If
End Sub
End Module
Now, if you target .NET Framework 4.0 (or higher) you can use a lambda expression for a quick, inline delegate:
Me.InvokeIfRequired( _
Sub()
If speedmodem >= 1 AndAlso speedmodem <= 500 Then
lblModCh.BackColor = Color.Green
ElseIf speedmodem >= 501 And speedmodem <= 1500 Then
lblModCh.BackColor = Color.Orange
ElseIf speedmodem >= 1501 Then
lblModCh.BackColor = Color.Red
ElseIf speedmodem = 0 Then
lblModCh.BackColor = Color.Black
End If
End Sub)
However if you target .NET Framework 3.5 or lower you have to create delegates the normal way:
Private Delegate Sub UpdatePingStatusDelegate(ByVal speedmodem As Integer)
Private Sub PingPublicTH()
...your code...
Me.InvokeIfRequired(New UpdatePingStatusDelegate(AddressOf UpdateStatusPublicTH), speedmodem)
End Sub
Private Sub UpdateStatusPublicTH(ByVal speedmodem As Integer)
If speedmodem >= 1 AndAlso speedmodem <= 500 Then
lblModCh.BackColor = Color.Green
ElseIf speedmodem >= 501 And speedmodem <= 1500 Then
lblModCh.BackColor = Color.Orange
ElseIf speedmodem >= 1501 Then
lblModCh.BackColor = Color.Red
ElseIf speedmodem = 0 Then
lblModCh.BackColor = Color.Black
End If
End Sub
Note:
When using the extension method InvokeIfRequired
you don't need to check Control.InvokeRequired
in the rest of your code. You only require the one call to the extension method and it will do the checking for you.
If you use my second method you only need the one UpdatePingStatusDelegate
delegate if all you need is one integer to update the status from all the threads.
Please also see the difference between And and AndAlso.