MyBackupRestore - CPU-Last zu hoch

  • Hallo,

    wegen der Übersichtlichkeit, habe ich meinem Backup Programm unten anderem eine neue Optik verpasst.

    Bis auf zwei Kleinigkeiten, klappt soweit alles.

    1. Die CPU-Last ist viel zu hoch
    2. Wenn ich einen der Buttons, Einstellungen, Datenaufnahme oder Protokoll klicke, kann ich danach kein Laufwerk mehr wählen.

    Was muss ich tun um das ListView zu reaktivieren?

    Das Programm generiert vorab eine Ini und sammelt die Notwendigen Daten für das Backup.

    Ablage: C:\Users\DeineID\MyBackupRestore\

    Leider reichen die 40.000 Zeichen für den Code nicht aus. Deshalb die Zip.

    MeineQuellen_1.0.0 muss vorab generiert werden.

    Das Programm generiert eine Ini und sammelt die Notwendigen Daten für das Backup.

    Ablage: C:\Users\DeineID\MyBackupRestore\

    Dateien

    myBackupRestore_1.0.8.zip

    Einmal editiert, zuletzt von mitac100 (24. März 2019 um 12:04)

  • Du solltest dir angewöhnen binäre Ressourcen nicht im Hauptskript abzuspeichern, das verlangsamt den Editor einfach nur unnötig.

    Lager sie in eine eigene .au3 aus und binde sie mit include ein. Deine zip ist auch nicht lauffähig, die OutlookExConstants fehlt.

    Es wäre schön wenn du uns verrätst wo dein Skript in eine Schleife gerät, bzw. welche Funktionen ausgeführt werden wenn du Sachen anklickst die andere unwählbar machen,

    damit wir uns nicht durch die tausende Zeilen kämpfen müssen.

  • Die CPU-Last ist viel zu hoch

    Das liegt an deinem Main-Loop, bzw. deiner While-Schleife...

    Code
    While 1
        Global $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
                Sleep(100) ; Das macht hier ja unheimlich viel Sinn! ;-)
        EndSwitch
    WEnd

    Im MsgMode wäre sie bis auf das überflüssige Sleep() fast korrekt... fast, weil die Variable $nMsg vor dem Loop deklariert werden sollte und anstelle des Global ein Local völlig ausreichend wäre.

    Im MsgMode schaltet die Funktion GUIGetMsg die CPU bei Bedarf automatisch in den Idle-Mode (Leerlauf), sodass sie in Schleifen sicher verwendet werden kann, ohne die gesamte CPU zu belasten.

    Da du aber mit allen GUI's im OnEventMode arbeitest, sollte deine While-Schleife (Main-Loop) so aussehen:

    Code
    While 1
        Sleep(10) ; 10-250 sind akzeptable Werte
    WEnd

    Wenn ich einen der Buttons, Einstellungen, Datenaufnahme oder Protokoll klicke, kann ich danach kein Laufwerk mehr wählen.

    Was muss ich tun um das ListView zu reaktivieren?

    Ich will dein Script bei mir nicht starten, weil sich die Spuren nur schwer beseitigen lassen. Meinst du mit Laufwerk auswählen geht danach nicht mehr, dass du keine Benachrichtigung mehr bekommst, wenn du mit der Maus in das Listview $Backup_Laufwerke_ListView bzw. $Restore_Laufwerke_ListView klickst?


    Hier noch ein paar Dinge, die mir beim Überfliegen deines Codes aufgefallen sind:


    Funktion _Bytes_KB_MB_GB

    Siehe _WinAPI_StrFormatByteSize, _WinAPI_StrFormatByteSizeEx und _WinAPI_StrFormatKBSize

    Code: __On_Button
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE ; <-- wird von __On_Close verarbeitet und trifft hier somit niemals zu

    Aus __On_Close und __On_Button würde ich eine Funktion __On_Event machen... alle Events in einer Funktion.


    Funktion _Laufwerke_ListViewBox

    If @UserName = @UserName Or @UserName = @UserName Then

    Hust... das macht natürlich Sinn... ;)

    Funktion _Backup_Laufwerke_WM_Notify_Events

    Hier hast du bei #forceref $hWndGUI als Parameter angegeben... wobei $hWndGUI aber nirgends deklariert wird. Richtig wäre hier wohl $hWnd.

    Wenn man mit mehreren GUI's hantierst, kann die Frage nach der ControlID u.U. ins Auge gehen, deshalb sollte dafür anstelle der ControlID besser das Handle des Controls verwendet werden.

    _GDIPlus_Startup() / _GDIPlus_Shutdown()

    _GDIPlus_Startup() solltest du einmalig beim Start ausführen, und _GDIPlus_Shutdown() ebenso, wenn das Script beendet wird.

    Code
    _GDIPlus_Startup()
    OnAutoItExitRegister('_Exit')
    
    ; Tu was...
    
    Exit
    
    Func _Exit()
        _GDIPlus_Shutdown()
    EndFunc
    Code
    For $j = 1 To $Drives[0]

    Laufvariablen würde ich nicht im globalen Kontext benutzen, weil dies später zu extrem schwer auffindbaren Fehlern führen kann. Analog dazu würde ich es auch möglichst vermeiden, globale Variablen innerhalb von Funktionen und Schleifen (s. Main-Loop) zu deklarieren.

    2 Mal editiert, zuletzt von Bitnugger (24. März 2019 um 09:18)

  • Du solltest dir angewöhnen binäre Ressourcen nicht im Hauptskript abzuspeichern, das verlangsamt den Editor einfach nur unnötig.

    Lager sie in eine eigene .au3 aus und binde sie mit include ein. Deine zip ist auch nicht lauffähig, die OutlookExConstants fehlt.

    Es wäre schön wenn du uns verrätst wo dein Skript in eine Schleife gerät, bzw. welche Funktionen ausgeführt werden wenn du Sachen anklickst die andere unwählbar machen,

    damit wir uns nicht durch die tausende Zeilen kämpfen müssen.

    Die Binarys habe ich ausgelagert, danke für den Tipp.

    Die OutlookExConstants wird nicht benötigt, ich habe sie dennoch in die neue zip im ersten Post eingefügt.

    Wenn ich eines der Laufwerke klicke wird darunter das Ziellaufwerk usw. angezeigt, siehe Bild.

    Sobald ich z.B. auf Einstellungen klicke und danach eine neues Laufwerk markiere, wird nicht das neue, sondern immer noch das zuvor gewählte Laufwerk angezeigt.

    In Zeile 1764 werden die _Backup_Einstellungen() aufgerufen. Der _Text_Editor ab 1961 und _Text_Editor_WM_NOTIFY ab 2042.

    Das ListView wird über die _Backup_Laufwerke_WM_Notify_Events Zeile 1517 gesteuert.

  • Danke Bitnugger, die CPU-Last ist jetzt auf 0.

    Code
    While 1
        Sleep(10) ; 10-250 sind akzeptable Werte
    WEnd

    Funktion _Laufwerke_ListViewBox

    If @UserName = @UserName Or @UserName = @UserName Then

    Hust... das macht natürlich Sinn... ;)


    Ja, macht es, wenn ich die notwendige Funktion eingebettet hätte.

    Es gibt eine Vorgabe, nach der die Sicherung auf einem USB-Stick erfolgen muss.

    Nur eine kleine Anzahl Personen soll auch die Lokalen Laufwerke sehen können.


    Mit dem obigen Code wird das Ziellaufwerk gar nicht mehr angezeigt. Ansonsten bleibt alles beim gleichen.

    Wenn ich die beiden Zeilen...

    Global $hBackup_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Backup_Laufwerke_ListView)

    Global $hRestore_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Restore_Laufwerke_ListView)

    ...vor der Funktion Platziere, erhalte ich die Meldung: Variable used without being declared

    Case $hBackup_Laufwerke_ListView

    Case ^ ERROR

    Wenn ich am Anfang des Scripts Global $hBackup_Laufwerke_ListView und Global $hRestore_Laufwerke_ListView einfüge udn vor der Funktion...

    $hBackup_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Backup_Laufwerke_ListView)

    $hRestore_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Restore_Laufwerke_ListView)

    ...wird zwar das Programm gestartet, bei der Wahl eine Ziellaufwerks, wird dieses nicht mehr angezeigt.

  • If @UserName = @UserName Or @UserName = @UserName Then

    -> Kommentar von Bitnugger : "Hust... das macht natürlich Sinn... ;) "

    Ja, macht es, wenn ich die notwendige Funktion eingebettet hätte.

    Also ich sehe den Sinn (wie auch Bitnugger ) nicht !

    Das Makro @UserName liefert die ID des momentan eingeloggten Users.

    If @UserName = @UserName or @UserName = @UserName ergibt immer True (ob mit oder ohne or)

    Aus Deinem Quelltext :

    If @UserName = @UserName or @UserName = @UserName Then $Drive_Set = DriveGetDrive("ALL")

    Du könntest demnach auch gleich :

    $Drive_Set = DriveGetDrive("ALL")

    schreiben !

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Wenn ich die beiden Zeilen...


    Global $hBackup_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Backup_Laufwerke_ListView)

    Global $hRestore_Laufwerke_ListView = ControlGetHandle($hGUI, '', $Restore_Laufwerke_ListView)


    ...vor der Funktion Platziere, erhalte ich die Meldung: Variable used without being declared

    Das Handle für ein Control besorgst du dir direkt nachdem du es erstellt hast, also eine oder ein paar Zeilen darunter.

    Zudem solltest du Variablen mit einem dem Typ entsprechenden Kürzel versehen... und globale Variablen sollten besser mit $g_ beginnen. Das hilft später ungemein bei der Fehlersuche!

    Global $g_idRestore_Laufwerke_ListView ; CtrlID

    Global $g_hRestore_Laufwerke_ListView ; Handle

    Global $g_sIniFile = @ScriptDir & '\IniFile.ini' ; String

    Global $g_iBackup_Einstellungen_Groesse ; Integer

    Global $g_aDrives ; Array

    Hier kannst du mehr dazu lesen: Best coding practices - AutoIt Wiki

    Variablen ausserhalb von Funktionen sind übrigens immer global, auch wenn du sie mit DIM oder Local deklarierst!

  • In Zeile 1764 werden die _Backup_Einstellungen() aufgerufen.Der _Text_Editor ab 1961 und _Text_Editor_WM_NOTIFY ab 2042.


    Das ListView wird über die _Backup_Laufwerke_WM_Notify_EventsZeile 1517 gesteuert.

    Dem Text habe ich entnommen, dass du mehrere Funktionen registriert hast, um Nachrichten für die Windows Message ID WM_NOTIFY auszuwerten...

    GUIRegisterMsg($WM_NOTIFY, "_Backup_Laufwerke_WM_Notify_Events")

    GUIRegisterMsg($WM_NOTIFY, "_Backup_Protokoll_WM_Notify_Events")

    GUIRegisterMsg($WM_NOTIFY, "_Text_Editor_WM_NOTIFY")

    ...das geht aber nicht, denn du kannst in deinem Script eine Message ID nur für eine Funktion registrieren - in deinem Fall ist dies nun _Text_Editor_WM_NOTIFY.

    Die Funktionen kannst du aber leicht zusammenlegen und dann, wie ich weiter oben bereits angemerkt hatte, besser mit $hWndFrom anstelle $iIDFrom hantieren.

    2 Mal editiert, zuletzt von Bitnugger (24. März 2019 um 19:23)