Multi-thread haning up main thread, going in order.

前端 未结 1 434
无人及你
无人及你 2021-01-27 10:13

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

相关标签:
1条回答
  • 2021-01-27 10:33

    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.

    0 讨论(0)
提交回复
热议问题