2014-11-03 59 views
0

我有,目前運行到針對約60種不同的網關一個ping監視我的客戶網絡的正常運行時間,因爲我想知道,如果他們的互聯網滴出在他們之前的應用程序。因此,目前我的應用程序通過一個從第一個(運行4個ping)開始的循環運行,等待2秒鐘,然後移動到下一個網關地址。然後,我執行了一些代碼,如果ping結果爲失敗,則重試很多次,因爲我希望在發送警報之前100%確定它們的連接已關閉。什麼是最好的方式來運行連續型的Ping多個IP地址

這種方法的問題是,在再次掃描同一個網關之前,需要大約1或2分鐘(或者更長的時間),這意味着如果連接在Ping後直接退出,我不會知道將近2分鐘。我知道這聽起來很微不足道,但我更願意立即向我的團隊發出警報,以便他們立即採取行動。

因此,我的問題是:它會更好(並且這將是影響)運行60個分開的ping(在不同的線程可能),而不是通過每一個循環。這樣我可以同時在每個網關上運行連續的ping。但是,我擔心對應用程序的性能影響,以及是否會在系統上造成太多負載。

任何意見,將不勝感激。由於

編輯

我已經創建了下面的代碼工作,但似乎嚴重影響單個處理器核心和,而該方法的工作,沒有錯誤,它似乎認爲該GUI作爲響應後不久:要做到這一點

Public Sub PingHost() 
    Try 
     GatewayScanning = True 
     For i As Integer = 0 To Gateways.Count - 1 
      Dim t As New Threading.Thread(AddressOf CheckHostOnline) 
      t.IsBackground = True 
      t.Start(Gateways(i)) 
     Next 

    Catch ex As Exception 
     ErrorTrap(ex, "OfflineClientHandler: PingHost()") 
    End Try 
End Sub 

Public Sub CheckHostOnline(ByVal gw As Object) 
    Try 
     Dim _gateway As Gateway_Object = DirectCast(gw, Gateway_Object) 
     Dim pingSender As New Ping() 
     Dim options As New PingOptions() 
     'Dim averageTime As Integer 
     Dim OfflinePingCount As Integer = 0 

     ' Use the default Ttl value which is 128, 
     ' but change the fragmentation behavior. 
     options.DontFragment = False 
     options.Ttl = 128 

     ' Create a buffer of 32 bytes of data to be transmitted. 
     Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
     Dim buffer() As Byte = Encoding.ASCII.GetBytes(data) 
     Dim timeout As Integer = 3000 

     Do While Not GatewayScanning = False 
      Dim reply As PingReply = pingSender.Send(_gateway.Gateway, timeout, buffer, options) 

      If reply.Status = IPStatus.Success Then 
       Dim resultTime As Integer = GetMs(CInt(reply.RoundtripTime)) 
       _gateway.Status = "ONLINE" 
       _gateway.Result = resultTime 
      Else 
       OfflinePingCount += 1 
       If OfflinePingCount < (My.Settings.OfflinePingCycleNumber * 4) Then 
        _gateway.Status = "TIMEOUT" 
        _gateway.Result = -1 
       Else 
        _gateway.Status = "OFFLINE" 
        _gateway.Result = -1 
       End If 
      End If 

      SyncLock class_OfflineGateways 
       class_OfflineGateways.UpdateListView(_gateway) 
      End SyncLock 

      System.Threading.Thread.Sleep(2000) 
     Loop 
     pingSender.Dispose() 

    Catch ex As Exception 
     ErrorTrap(ex, "OfflineClientHandler: CheckHostOnline()") 
    End Try 

End Sub 
+0

是你的客戶服務,讓關鍵任務上的停機時間__theoretical__2分鐘鉛是必不可少的?考慮你或你的客戶被告知的方法。例如,當你發送電子郵件,短信,你有什麼?他們甚至會立即收到你的信息(或在兩分鐘,十分鐘,一小時內)。這些服務是否有專門的應急人員每天24小時提供服務? – 2014-11-03 13:07:22

+0

如果爲已建立接受連接的每個網關創建一個線程,該怎麼辦?這樣,您可以允許每個線程單獨管理自己,就時間而言。從那裏你可以擁有一個線程可以調用的共享對象來更新一個布爾標誌,指示連接是否仍然存在。 – Ckrempp 2014-11-03 17:08:43

+0

@JustinRyan當網關涉及電子支付系統時,它確實成爲關鍵任務。當他們的支付系統下線並告訴我2分鐘不是很長時間時,請嘗試站在繁忙的零售店排隊! :) – Riples 2014-11-04 00:43:17

回答

1

一種方式是通過循環在不同的線程60 IPS,並且需要五秒(或一定量的時間)延遲再次開始循環之前。

另一種方式是我們異步ping命令,而不是單獨的線程。

上次我這樣做,我結束了使用一個單獨的線程與10毫秒睡覺ping之間的延遲。每當我將它們聚集在一起時,ping線失敗太多,無論是線程還是異步ping。我從來沒有弄清楚問題是在服務器端還是在目標網絡上。

這是我用來ping IP地址列表的一類。它(和其他一些東西)在ISP服務器上作爲服務運行。 (我發現我仍然BackgroundWorker的聲明,儘管它不再使用。)

Imports System.Net 
Imports System.Threading 
Imports System.Collections.Generic 

Class pingGroup 
' used to ping each IP in Targets 

Public Targets As New List(Of IPAddress) 
Public sectorID As Integer 
Public nErrors As Integer = 0 
Public Timeout As Integer = pingTimeout 

Public PingLog As New List(Of String) 
Public PingAvg As Integer = -2 ' -2 = uninit, -1 = error, else average ms excluding the slowest 
Public PingTime As DateTime 

Public pingCount As Integer = 0 
Public pingStarts As Integer = 0 
Dim msTotal As Integer = 0 

Dim WithEvents bkgPing As System.ComponentModel.BackgroundWorker 

Public Sub New(ByVal groupSectorID As Integer) 
sectorID = groupSectorID 
End Sub 

Public Sub Ping() 
' run a pingtest once, adding the result incrementally 

Dim ip As IPAddress 
Dim reply As NetworkInformation.PingReply 
Dim ms As Integer 

PingTime = Now 

If PingLog.Count <= 0 Then PingLog.Add(Format(Now, "G") & " Ping Test") 

For Each ip In Targets 
    Using pPing As New NetworkInformation.Ping 
    Try 
     pingStarts = pingStarts + 1 
     reply = pPing.Send(ip, Timeout) 
     If reply.Status = NetworkInformation.IPStatus.Success Then 
     ms = reply.RoundtripTime 
     pingCount = pingCount + 1 
     msTotal = msTotal + ms 
     If pingCount > 0 Then PingAvg = msTotal/pingCount 
     PingLog.Add(reply.Address.ToString & " " & ms) 
     Else 
     nErrors = nErrors + 1 
     PingLog.Add(Format(Now, "G") & " ---Ping Error: " & ip.ToString & " " & reply.Status.ToString) 
     End If 

    Catch ex As Exception 
     nErrors = nErrors + 1 
     PingLog.Add(Format(Now, "G") & " ===Ping Error: " & ip.ToString & " " & ex.Message) 
     End Try 
    End Using 
    Thread.Sleep(10) 
    Next ip 

End Sub 

End Class 
+0

Xpda - 你有一個例子如何做到這一點?我寫了我的代碼來運行連續的ping,但我在創建60個獨立的線程來運行這個問題上有問題,因爲我需要將參數傳遞給我的子例程。 – Riples 2014-11-06 04:44:06

+0

我添加了一些我以前用過的代碼。我決定反對異步或多線程。 – xpda 2014-11-06 06:37:59

+0

創建一個接收要ping的IP地址的類,具有記錄此IP的ping狀態的功能並對此IP執行其他操作。 然後爲IP地址列表創建線程池,爲每個IP地址創建一個類的實例並在線程中運行,最後等待所有線程結束。這將使應用程序繼續運行。 – 2014-11-06 06:45:26

相關問題