Ping blockiert bzw. ist zu langsam

  • Hallo,

    ich nutze eine "gefundene" und konvertierte .VBS-Funktion, um Rechnername/IP in meiner ListView anzupingen und je nach Status auf online/offline zu setzen (grün/rot).
    Allerdings "blockiert" mir diese das ganze Programm, bis es durch die ~300 Rechner ist - schätzungsweise 1-2 Sekunden pro Offline-Rechner.

    Geht das igendwie im Hintergrund bzw. von mir aus auch schneller??
    p.s. das mit dem temp-File auslesen unten habe ich schon mal versucht durch das stdio-einlesen zu ersetzen, ist also nur eine andere Variante..

    Spoiler anzeigen
    [autoit]


    Func _IPTest()
    GUICtrlSetState($ButIPScan, $GUI_DISABLE)
    For $i = 0 to $iAnzahlPC-1
    $RDP = _GUICtrlListView_GetItemText($LVPC, $i)
    ;ConsoleWrite($rdp & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    if IsConnectible($RDP) = 1 Then
    _GUICtrlListView_SetItemImage( $LVPC, $i, 2)
    Else
    _GUICtrlListView_SetItemImage( $LVPC, $i, 0)
    EndIf
    Next
    GUICtrlSetState($ButIPScan, $GUI_ENABLE)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func IsConnectible($sHost, $iPings=2, $iTO=150)

    [/autoit] [autoit][/autoit] [autoit]

    If $iPings = "" Then $iPings = 2
    If $iTO = "" Then $iTO = 150

    [/autoit] [autoit][/autoit] [autoit]

    Const $OpenAsDefault = -2
    Const $FailIfNotExist = 0
    Const $ForReading = 1

    [/autoit] [autoit][/autoit] [autoit]

    Local $oShell = ObjCreate("WScript.Shell")
    Local $oFSO = ObjCreate("Scripting.FileSystemObject")
    Local $sTemp = $oShell.ExpandEnvironmentStrings("%TEMP%")
    Local $sTempFile = $sTemp & "\runresult.tmp"

    [/autoit] [autoit][/autoit] [autoit]

    $oShell.Run( "%comspec% /c ping -n " & $iPings & " -w " & $iTO & " " & $sHost & ">" & $sTempFile, 0 , True)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fFile = $oFSO.OpenTextFile($sTempFile, $ForReading, $FailIfNotExist, $OpenAsDefault)

    [/autoit] [autoit][/autoit] [autoit]

    Local $sResults = $fFile.ReadAll
    $fFile.Close
    $oFSO.DeleteFile($sTempFile)

    [/autoit] [autoit][/autoit] [autoit]

    If StringInStr($sResults,"TTL=") Then
    Return 1
    Else
    Return 0
    EndIf
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von Torni (26. März 2013 um 22:37)

  • Ich sehe nichts in deinem Skriptschnipsel was blockiert werden könnte. Ein externer Pingaufruf benötigt aber zusätzlich Zeit, da ja das Programm gestartet, initialisiert und nach dem Ergebnis ausgewertet werden muss. Andererseits kannst du dadurch die Aufrufe auch parallelisieren. Dazu müsstest du die PIDs der gestarteten Aufrufe in einem Array speichern und in einer separaten mit Adlibregister registrierten Func auswerten.

    mfg autoBert

  • Dann arbeite eben mit einem externen "WorkerScript". Das Hauptprogramm startet mehrere Instanzen dieses Scripts und prüft z.B. in seiner GUI Schleife ob die derzeit laufenden "WorkerScripte" fertig sind, wenn ja wird deren Ergebnis ins Listview eingetragen. Dadurch blockiert nichts mehr und du kannst sogar mehrere oder alle (würde ich bei 300 Rechnern vermeiden) Pings zeigleich laufen lassen.

    Das "WorkerScript" könnte dann recht simpel sein und würde mit wenigen Zeilen Code auskommen.

    meinePing.exe

    [autoit]


    #notrayicon
    ; prüfe Parameter
    if $cmdline[0] < 1 then exit msgbox(0,"Fehler","Bitte gib die IP-Adresse als Parameter an")
    $ip = $cmdline[1]

    [/autoit][autoit][/autoit][autoit]

    ; pinge rechner
    $ergebnis = ping($ip)
    $errorcode = @error

    [/autoit][autoit][/autoit][autoit]

    ; gebe Ergebnis an Hauptprogramm weiter
    if $ergebnis = 0 then
    $rueckgabe = "Error: " & $errorcode
    else
    $rueckgabe = $ergebnis
    endif
    ; hier gibt es nun tausende möglichkeiten den Wert von $rueckgabe ans Hauptprogramm zu übergeben, siehe dazu die Suche des Forums zum Thema Kommunikation zweier Scripte

    [/autoit][autoit][/autoit][autoit][/autoit]


    Aufgerufen wird das ganze dann vom Hauptprogramm z.B. so oder so ähnlich:

    [autoit]


    for $i = 0 to ubound($aIP)-1
    $laufendeProzesse[$i]=run(@scriptdir & "\meinePing.exe " & $aIP[$i])
    next

    [/autoit]

    Und ja wenn man das sinnvoll lösen will wird es durch die Aufteilung in 2 Programme etwas komplexer, aber letztlich ist es so deutlich performanter.