2017-01-25 5 views
0

私はメインスレッドをハングアップしているマルチスレッドのpingに問題があります。問題をデバッグするとき、私は、メインスレッドがハングアップしている間に、各スレッドを開始し、次のpingに移動していることに気付きます。基本的に5つの異なるIPアドレスをpingする必要があります。もしそれらがすべてダウンしていると、スレッド全体が20〜30秒間ハングアップします。私はBeginInvokeを使用していますが、それでも正しい動作をしていないようです。マルチスレッドはメインスレッドをハングアップし、順番に実行します。

もう1つの奇妙な点は、各スレッドの最後にメッセージボックスを追加して、完了しているかどうかを確認することです。私は5つのスレッドがあり、それぞれの最後にポップアップして「完了」と表示されるメッセージボックスがあります。まあ、ちょうど5回ポップアップするのではなく、2回走っているかのように10倍になります。通常、私はこれらのスレッドにメッセージボックスを持っていませんが、何が起こっているのか把握しようとするだけですが、私は困惑しています。

これは、IPアドレスを取得し、スレッドを開始します:

Private Sub PingThreadStart() 

    Host = zeroStoreNum 


    IP = "10." 
    Select Case (Host.Substring(0, 1)) 
     Case "0" 
      IP = IP & "10." 
     Case "1" 
      IP = IP & "11." 
     Case "2" 
      IP = IP & "12." 
     Case "3" 
      IP = IP & "13." 
     Case "4" 
      IP = IP & "14." 
     Case "5" 
      IP = IP & "15." 
     Case "6" 
      IP = IP & "16." 
     Case "7" 
      IP = IP & "17." 
     Case "8" 
      IP = IP & "18." 
     Case "9" 
      IP = IP & "19." 
    End Select 

    Select Case (Host.Substring(1, 1)) 
     Case "0" 
      'IP = IP & "0" 
     Case "1" 
      IP = IP & "1" 
     Case "2" 
      IP = IP & "2" 
     Case "3" 
      IP = IP & "3" 
     Case "4" 
      IP = IP & "4" 
     Case "5" 
      IP = IP & "5" 
     Case "6" 
      IP = IP & "6" 
     Case "7" 
      IP = IP & "7" 
     Case "8" 
      IP = IP & "8" 
     Case "9" 
      IP = IP & "9" 
    End Select 

    Select Case (Host.Substring(2, 1)) 
     Case "0" 
      IP = IP & "0." 
     Case "1" 
      IP = IP & "1." 
     Case "2" 
      IP = IP & "2." 
     Case "3" 
      IP = IP & "3." 
     Case "4" 
      IP = IP & "4." 
     Case "5" 
      IP = IP & "5." 
     Case "6" 
      IP = IP & "6." 
     Case "7" 
      IP = IP & "7." 
     Case "8" 
      IP = IP & "8." 
     Case "9" 
      IP = IP & "9." 
    End Select 
    If Host = 100 Then 
     IP = "10.10.100." 
    End If 
    If Host = 200 Then 
     IP = "10.11.100." 
    End If 
    If Host = 300 Then 
     IP = "10.12.100." 
    End If 
    If Host = 400 Then 
     IP = "10.13.100." 
    End If 
    If Host = 500 Then 
     IP = "10.14.100." 
    End If 
    If Host = 600 Then 
     IP = "10.15.100." 
    End If 
    If Host = 700 Then 
     IP = "10.16.100." 
    End If 
    If Host = 800 Then 
     IP = "10.17.100." 
    End If 
    If Host = 900 Then 
     IP = "10.18.100." 
    End If 

    lblIPschemeCH.Text = IP & "X" 

    SonicWALL = IP & "1" 
    primary = IP & "2" 
    secondary = IP & "3" 

    Dim PingPublicTry As Thread = New Thread(AddressOf PingPublicTH) 
    Dim PingSWpublicTry As Thread = New Thread(AddressOf PingSWpublicTH) 
    Dim PingDotOneTry As Thread = New Thread(AddressOf PingDotOneTH) 
    Dim PingDotTwoTry As Thread = New Thread(AddressOf PingDotTwoTH) 
    Dim PingDotThreeTry As Thread = New Thread(AddressOf PingDotThreeTH) 

    PingPublicTry.IsBackground = True 
    PingSWpublicTry.IsBackground = True 
    PingDotOneTry.IsBackground = True 
    PingDotTwoTry.IsBackground = True 
    PingDotThreeTry.IsBackground = True 


    If ModemPublic = "DHCP" Or SonicWALLPublic = "DHCP" Then 
     PingDotOneTry.Start() 
     PingDotTwoTry.Start() 
     PingDotThreeTry.Start() 
    Else 
     PingPublicTry.Start() 
     PingSWpublicTry.Start() 
     PingDotOneTry.Start() 
     PingDotTwoTry.Start() 
     PingDotThreeTry.Start() 
    End If 



End Sub 

そして、これが私のトレッドである:

Private Sub PingPublicTH() 
    Dim pingactmodem As New System.Net.NetworkInformation.Ping 
    Dim pingretmodem As System.Net.NetworkInformation.PingReply 
    Dim speedmodem As Integer 

    Try 
     pingretmodem = pingactmodem.Send(ModemPublic) 
     speedmodem = pingretmodem.RoundtripTime 
    Catch ex As Exception 

    End Try 

    If (lblModCh.InvokeRequired) Then 

     Dim show As New PingPublicDel(AddressOf PingPublicTH) 
     Me.lblModCh.BeginInvoke(show) 
    Else 
     If speedmodem >= 1 And 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 If 
    MessageBox.Show("Done modem") 


End Sub 
Private Sub PingSWpublicTH() 
    Dim pingactswp As New System.Net.NetworkInformation.Ping 

    Dim pingretswp As System.Net.NetworkInformation.PingReply 
    Dim speedswp As Integer 

    Try 
     pingretswp = pingactswp.Send(SonicWALLPublic) 
     speedswp = pingretswp.RoundtripTime 
    Catch ex As Exception 
    End Try 

    If (lbSWPCh.InvokeRequired) Then 

     Dim show As New PingSwPublicDel(AddressOf PingSWpublicTH) 
     Me.lbSWPCh.BeginInvoke(show) 
    Else 
     If speedswp >= 1 And speedswp <= 500 Then 
      lbSWPCh.BackColor = Color.Green 
     ElseIf speedswp >= 501 And speedswp <= 1500 Then 
      lbSWPCh.BackColor = Color.Orange 
     ElseIf speedswp >= 1501 Then 
      lbSWPCh.BackColor = Color.Red 
     ElseIf speedswp = 0 Then 
      lbSWPCh.BackColor = Color.Black 

     End If 

    End If 
    MessageBox.Show("Done swp") 

End Sub 
Private Sub PingDotOneTH() 
    Dim pingact1 As New System.Net.NetworkInformation.Ping 
    Dim pingret1 As System.Net.NetworkInformation.PingReply 
    Dim speed1 As Integer 



    pingret1 = pingact1.Send(SonicWALL) 
    speed1 = pingret1.RoundtripTime 

    If (lblSWch.InvokeRequired) Then 

     Dim show As New PingDotOneDel(AddressOf PingDotOneTH) 
     Me.lblSWch.BeginInvoke(show) 

    Else 

     If speed1 >= 1 And speed1 <= 500 Then 
      lblSWch.Text = (speed1) 
      lblSWch.BackColor = Color.Green 
     ElseIf speed1 >= 501 And speed1 <= 1500 Then 
      lblSWch.Text = (speed1) 
      lblSWch.BackColor = Color.Orange 
     ElseIf speed1 >= 1501 Then 
      lblSWch.Text = (speed1) 
      lblSWch.BackColor = Color.Red 
     ElseIf speed1 = 0 Then 
      lblSWch.Text = "Down" 
      lblSWch.BackColor = Color.Black 

     End If 
    End If 
    MessageBox.Show("Done .1") 
End Sub 
Private Sub PingDotTwoTH() 
    Dim pingact2 As New System.Net.NetworkInformation.Ping 
    Dim pingret2 As System.Net.NetworkInformation.PingReply 
    Dim Speed2 As Integer 


    pingret2 = pingact2.Send(primary) 
    Speed2 = pingret2.RoundtripTime 

    If (lblMainpcCH.InvokeRequired) Then 
     Dim show As New PingDotTwoDel(AddressOf PingDotTwoTH) 
     Me.lblMainpcCH.BeginInvoke(show) 

    Else 

     If Speed2 >= 1 And Speed2 <= 500 Then 
      lblMainpcCH.Text = (Speed2) 
      lblMainpcCH.BackColor = Color.Green 
     ElseIf Speed2 >= 501 And Speed2 <= 1500 Then 
      lblMainpcCH.Text = (Speed2) 
      lblMainpcCH.BackColor = Color.Orange 
     ElseIf Speed2 >= 1501 Then 
      lblMainpcCH.Text = (Speed2) 
      lblMainpcCH.BackColor = Color.Red 
     ElseIf Speed2 = 0 Then 
      lblMainpcCH.Text = "Down" 
      lblMainpcCH.BackColor = Color.Black 

     End If 

    End If 
    MessageBox.Show("Done .2") 
End Sub 
Private Sub PingDotThreeTH() 
    Dim pingact3 As New System.Net.NetworkInformation.Ping 
    Dim pingret3 As System.Net.NetworkInformation.PingReply 
    Dim speed3 As Integer 



    pingret3 = pingact3.Send(secondary) 
    speed3 = pingret3.RoundtripTime 


    If (lblSecondch.InvokeRequired) Then 

     Dim show As New PingDotThreeDel(AddressOf PingDotThreeTH) 

     Me.lblSecondch.BeginInvoke(show) 

    Else 

     If speed3 >= 1 And speed3 <= 500 Then 
      lblSecondch.Text = (speed3) 
      lblSecondch.BackColor = Color.Green 
     ElseIf speed3 >= 501 And speed3 <= 1500 Then 
      lblSecondch.Text = (speed3) 
      lblSecondch.BackColor = Color.Orange 
     ElseIf speed3 >= 1501 Then 
      lblSecondch.Text = (speed3) 
      lblSecondch.BackColor = Color.Red 
     ElseIf speed3 = 0 Then 
      lblSecondch.Text = "Down" 
      lblSecondch.BackColor = Color.Black 

     End If 

    End If 
    MessageBox.Show("Done .3") 
End Sub 
+0

「show」メソッドも表示してください。 –

+0

@VisualVincent私はあなたが何を意味するのか正確には分からないので、そこに問題があると仮定しています。スレッド自体にShowを作成します。 「新しいPingPublicDelとして表示する(AddressOf PingPublicTH)」 – Joshm

+0

ああ、私はそれが変数であることはわかりませんでした(私は現在電話にいます)。私は問題を見つけ、答えを書いた。 –

答えて

2

ここでの問題は、あなたがなっている、もう一度同じメソッドを呼び出すことですスレッドで実行されます。これにより、もう一度ping要求が送信されますが、今回はコードがUIスレッド上で実行されます(したがって、なぜフリーズするのか)。 UIを更新するコードのみを呼び出すようにしてください。

これはオプションですが、私はそれが可読性を向上させるだけでなく、あなたが書かなければならないコードの量減少するので、あなたはあなたのための呼び出しのチェックを行うためにextension methodを使用することをお勧めします。

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 

を今の場合、あなたは、ターゲットの.NET Framework 4.0(またはそれ以上)あなたが迅速、インラインデリゲートのためlambda expressionを使用することができます:あなたは、.NET をターゲットただし

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) 

Framework 3.5のまたはあなたが代表者に通常の方法を作成する必要が下げる:

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 

注:

  • あなたがの残りの部分でControl.InvokeRequiredをチェックする必要はありませんInvokeIfRequired拡張メソッドを使用してあなたのコード。拡張メソッドへの1回の呼び出しだけが必要で、それはあなたのためのチェックを行います。

  • 2番目の方法を使用する場合は、すべてのスレッドからステータスを更新するために必要なものが1つだけあれば、UpdatePingStatusDelegate代理人が1人必要です。

the difference between And and AndAlsoも参照してください。

+0

私は私の電話からこの答えを書いたことに注意してください。それがあなたのために働かないなら、私はできるだけ早くそれをテストします。 –

+0

ありがとう!インストールには4.5xが必要でした。できるだけ早く回答を取り入れ、結果を教えてあげます。 ありがとうございました。 – Joshm

関連する問題