2015-09-20 5 views
0

Я создаю довольно простой инструмент ping, который показывает в миллисекундах, сколько времени сервер взял для ответа. Если сервер не отвечает, он показывает, как он ответил в 0 мс. Я хотел реализовать инструкцию If для записи Server failed to respond в ListBox, а не в 0ms. Единственная проблема с этим - у меня есть кусок кода, который нужно запускать за пределами If, но он продолжается внутри If и включает в себя использование строки кода Next ... Кажется, это приводит к тому, что оператор If не распознает End If и End If не признают If ...Оператор FOR, противоречащий выражению IF в VB

Вот мой код:

For i As Integer = 0 To numberOfPings - 1 
     Dim ping As New Ping 
     Dim pingRe As PingReply = ping.Send(pingTarget) 

     If pingRe.RoundtripTime = 0 Then 
      Me.listboxPing.Items.Add("Server failed to respond...") 
     Else 

      Me.listboxPing.Items.Add("Response from " & pingTarget & " in " & pingRe.RoundtripTime.ToString() & "ms") 
      listboxPing.SelectedIndex = listboxPing.Items.Count - 1 
      listboxPing.SelectedIndex = -1 
      Application.DoEvents() 

      Threading.Thread.Sleep(500) 
    Next 



    Me.listboxPing.Items.Add("") 


     End If 

кто-нибудь знает, как я мог это исправить/обойти эту проблему?

Thanks,

+0

Поскольку ваш 'If' начинается внутри' For', он должен заканчиваться внутри 'For'. Другими словами, 'End If' должен появиться перед' Next'. Это очень похоже на балансирующие круглые скобки. – dasblinkenlight

+0

@dasblinkenlight Я понимаю это, но мне нужно 'Next' и' Me.listboxPing.Items.Add ("") 'находиться внутри' Else' 'If' ... –

+0

Имея' Next' внутри 'Else' это невозможно. Придумайте другую структуру для вашего кода, так что 'Next' находится за пределами условного. – dasblinkenlight

ответ

0

Это вы, что после?

For i As Integer = 0 To numberOfPings - 1 
     Dim ping As New Ping 
     Dim pingRe As PingReply = ping.Send(pingTarget) 

     If pingRe.RoundtripTime = 0 Then 
      Me.listboxPing.Items.Add("Server failed to respond...") 
     Else 

      Me.listboxPing.Items.Add("Response from " & pingTarget & " in " & pingRe.RoundtripTime.ToString() & "ms") 
      listboxPing.SelectedIndex = listboxPing.Items.Count - 1 
      listboxPing.SelectedIndex = -1 
      Application.DoEvents() 

      Threading.Thread.Sleep(500) 
      add = True 
      Exit For 
     End If 
    Next 

If add Then Me.listboxPing.Items.Add("") 

The If изменит область действия, поэтому вам нужно использовать переменную, чтобы проверить, попала ли она в часть Else.

Конечно, вам нужно закрыть первое. Если перед следующим.

+0

Это заставило мою программу замерзнуть, и мне пришлось принудительно закрыть ее с помощью диспетчера задач ... Любые предложения относительно того, почему это могло произойти? Это не дает мне отчета о сбоях или говорит мне, почему он разбился, он просто замерзает и отказывается что-то делать ... –

+0

Также после этого он остановил окно, которое определяет, как время, которое сервер будет пинговать от работы. Он просто пингов один раз, сколько раз пользователь определяет ... –

+0

Если он немного зависает перед сбоем, я бы приостановил отладку, чтобы увидеть, в каком заявлении он застрял; который должен предоставить вам достаточно информации, если это не так, я бы попытался использовать WinDbg с SOS для получения более подробной информации об отладке. Я не могу сказать вам, где проблема с этим кодом, но я бы постарался не блокировать пользовательский интерфейс с помощью задач, а не Application.DoEvents(), он может застревать перед выполнением инструкции и, следовательно, не обрабатывать очередь сообщений. –

1

Если бы я собирался написать код для ping-адреса и показать результаты, он будет выглядеть примерно так.

Dim pingThrd As Threading.Thread 

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then 
     RichTextBox1.Clear() 
     pingThrd = New Threading.Thread(AddressOf PingIt) 
     pingThrd.IsBackground = True 
     pingThrd.Start("192.168.33.1") 
    End If 
End Sub 

Public Sub PingIt(pingTarget As Object) 
    Dim numberOfPings As Integer = 5 
    Dim pingT As String = DirectCast(pingTarget, String) 
    Dim pingTimeOut As Integer = 1000 
    Const dlyBetweenPing As Integer = 500 

    Dim dspStr As String 

    For i As Integer = 0 To numberOfPings - 1 
     Dim pingit As New Ping 
     Dim pingRe As PingReply = pingit.Send(pingT, pingTimeOut) 
     'check if success 
     If pingRe.Status = IPStatus.Success Then 
      dspStr = String.Format("Response from: {0} in {1}ms.", pingRe.Address, pingRe.RoundtripTime) 
     Else 
      dspStr = String.Format("{0} failed. Status: {1}", pingRe.Address, pingRe.Status) 
     End If 
     Me.BeginInvoke(Sub() 
          RichTextBox1.AppendText(dspStr) 
          RichTextBox1.AppendText(Environment.NewLine) 
         End Sub) 
     Threading.Thread.Sleep(dlyBetweenPing) 
    Next 
End Sub 

Редактировать: Одинаковый базовый код, но разрешить поток начинать с другого адреса и подсчета.

Structure PingWhat 
    Dim addr As String 
    Dim howmany As Integer 
End Structure 

Dim pingThrd As Threading.Thread 

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then 
     RichTextBox1.Clear() 
     'setup a thread to do the actual ping'ing 
     'this allows the UI to function 
     pingThrd = New Threading.Thread(AddressOf PingIt) 
     pingThrd.IsBackground = True 
     'setup address to ping and howmany times to ping it 
     Dim somePing As New PingWhat With {.addr = "192.168.33.1", .howmany = 3} 
     'start the thread 
     pingThrd.Start(somePing) 
    End If 
End Sub 

Public Sub PingIt(pingTarget As Object) 
    Dim pingT As PingWhat = DirectCast(pingTarget, PingWhat) 
    Dim pingTimeOut As Integer = 1000 
    Const dlyBetweenPing As Integer = 500 

    Dim dspStr As String 

    For i As Integer = 1 To pingT.howmany 
     Dim pingit As New Ping 
     Dim pingRe As PingReply = pingit.Send(pingT.addr, pingTimeOut) 
     'check if success 
     If pingRe.Status = IPStatus.Success Then 
      dspStr = String.Format("Response from: {0} in {1} ms.", pingRe.Address, pingRe.RoundtripTime) 
     Else 
      dspStr = String.Format("Ping Failed {0}. Status: {1}", pingT.addr, pingRe.Status) 
     End If 
     'update the UI 
     Me.BeginInvoke(Sub() 
          RichTextBox1.AppendText(dspStr) 
          RichTextBox1.AppendText(Environment.NewLine) 
          RichTextBox1.ScrollToCaret() 
         End Sub) 
     Threading.Thread.Sleep(dlyBetweenPing) 
    Next 
    Me.BeginInvoke(Sub() 
         RichTextBox1.AppendText("Done") 
         RichTextBox1.AppendText(Environment.NewLine) 
         RichTextBox1.ScrollToCaret() 
        End Sub) 
End Sub 
+0

Это происходит где-то внутри моего существующего кода или это ПОЛНЫЙ пинг-скрипт? –

+0

Полный. Попробуйте. Создайте новый проект с помощью кнопки и richtextbox. – dbasnett

+0

И где же введен IP-адрес пользователя? Также есть ли у пользователя возможность выбирать, сколько раз пингует цель? –

0

@dbasnett Это код, который я использовал раньше, и это было абсолютно идеально подходит для того, что мне нужно, КРОМЕ если пинг не удался было бы просто сказать (PingTarget) responded in 0ms, который не является идеальным. В идеале я хотел бы сказать Server failed to respond.... Знаете ли вы, каким образом это может быть достигнуто путем изменения моего исходного кода?

Imports System.Net.NetworkInformation 
Imports System.Runtime.InteropServices 
Public Class PingClient 



    Private Const EM_SETCUEBANNER As Integer = &H1501 

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> 
    Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As Int32 
    End Function 

    Private Sub SetCueText(ByVal control As Control, ByVal text As String) 
     SendMessage(control.Handle, EM_SETCUEBANNER, 0, text) 
    End Sub 

    Private Sub PingClient_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     SetCueText(textboxIP, "IP Address/Domain") 
     SetCueText(textboxPing, "No. Of Pings") 
    End Sub 

Structure PingWhat 
    Dim addr As String 
    Dim howmany As Integer 
End Structure 

Dim pingThrd As Threading.Thread 

Public Sub buttonPing_Click(sender As Object, e As EventArgs) Handles buttonPing.Click 

    If pingThrd Is Nothing OrElse pingThrd.ThreadState = Threading.ThreadState.Stopped Then 
     Dim pingTarget As String = "" 
     Dim numberOfPings As Integer = 0 
     Dim intTimeout As Integer = 2000 

     If String.IsNullOrEmpty(textboxIP.Text) Then 
      MsgBox("You must enter an IP Address or Domain.") 
      Exit Sub 
     End If 

     If Not Int32.TryParse(textboxPing.Text, numberOfPings) Then 
      MsgBox("You must enter a number of how many times the target address will be pinged.") 
      Exit Sub 
     End If 

     If numberOfPings = 0 Then 
      MsgBox("You must enter a value over 0.") 
      textboxPing.Clear() 
      Exit Sub 
     End If 

     'setup a thread to do the actual ping'ing 
     'this allows the UI to function 
     pingThrd = New Threading.Thread(AddressOf PingIt) 
     pingThrd.IsBackground = True 
     'setup address to ping and howmany times to ping it 
     Dim somePing As New PingWhat With {.addr = pingTarget, .howmany = numberOfPings} 
     'start the thread 
     pingThrd.Start(somePing) 
    End If 

    Me.listboxPing.Items.Add("") 

End Sub 

Public Sub PingIt(pingTarget As Object) 
    Dim pingT As PingWhat = DirectCast(pingTarget, PingWhat) 
    Dim pingTimeOut As Integer = 1000 
    Const dlyBetweenPing As Integer = 500 

    Dim dspStr As String 

    For i As Integer = 1 To pingT.howmany 
     Dim pingit As New Ping 
     Dim pingRe As PingReply = pingit.Send(pingT.addr, pingTimeOut) 
     'check if success 
     If pingRe.Status = IPStatus.Success Then 
      dspStr = String.Format("Response from: {0} in {1} ms.", pingRe.Address, pingRe.RoundtripTime) 
     Else 
      dspStr = String.Format("Ping Failed {0}. Status: {1}", pingT.addr, pingRe.Status) 
     End If 
     'update the UI 
     Me.BeginInvoke(Sub() 
          listboxPing.Items.Add(dspStr) 
         End Sub) 
     Threading.Thread.Sleep(dlyBetweenPing) 
    Next 
    Me.BeginInvoke(Sub() 
         listboxPing.Items.Add("Done") 
        End Sub) 
End Sub 


    Private Sub PingClient_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing 
     Dim Response As Integer 
     Response = MsgBox("Are you sure you want to exit the Ping Tool?", 36) 

     If Response = MsgBoxResult.Yes Then 

     Else 

      e.Cancel = True 
     End If 
    End Sub 

End Class 
+0

Я отредактировал этот код. – dbasnett

+1

Этот код очень похож на части ответа mr dbasnett. Наверняка, он заслуживает поддержки, нет? Это не обойдется вам ни в чем, что бы вы ни выбрали, где бы вы ни учились. Один голос за 10 месяцев кажется немного редким. – Plutonix

Смежные вопросы