(Anfänger)Mehrere Schleifen gleichzeitig?

  • Hallöchen,

    ich versuche in letzter Zeit mich ein wenig mit AutoIT zu befassen. Bis hierhin habe ich meine Probleme auch immer mit Google lösen können, aber für mein derzeitiges Problem konnte ich einfach keine Lösung finden. Eigentlich ist das, was ich (ver)suche, relativ einfach gedacht:

    Ich habe mehrere Befehle. Sagen wir es sind 3, welche jeweils verschiedene sleep(zeiten) haben. Mein Problem ist jetzt, dass ich mit einer While schleife nur so vorgehen kann:

    While 1
    Befehl #1
    Sleep(x)
    Befehl #2
    Sleep(y)
    Befehl #3
    Sleep(z)
    WEnd

    Das ganze von vorne. Jeder Befehl wird nach dem nächsten ausgeführt.

    Ich hätte aber gerne, dass alle 3 Befehle zeitgleich fungieren. Also alle zur selben Zeit gestartet werden & im unendlich loop wiederholt werden - ohne dass der eine Befehl auf die Beendigung eines anderen warten muss. Ich habe versucht verschiedene While schleifen zu benutzen,(d.h. für jeden Befehl habe ich eine While Schleife geschrieben) das hat aber irgendwie nicht geklappt.

    Wäre nett, wenn mir jemand hierbei helfen könnte. Ich entschuldige mich, falls diese Frage schon gestellt wurde - ich habe gesucht, aber nichts gefunden, was mir mein Problem gelöst bzw. verständlich erklärt hat.

    MfG

  • Hallo!
    Ich Denke du meinst so etwas wie Threading, und das ist so in AU3 leider nicht möglich (Mit erweiterten Kenntnissen und Processing schon...). Du wirst deine Schleife so aufbauen müssen, das eben Funktion für Funktion aufgerufen wird. Nur in den seltensten Fällen braucht man wirklich Threading!
    Wenn du etwas darüber Nachdenkst, wird dir sicherlich eine bessere Möglichkeit einfallen.

    Grüße!

  • Hi wie Techmix bereits sagte unterstützt AutoIt kein Mulithreading. Sollten aber die Aufgaben der Funktionen nicht besonders Aufwendig sein empfehle ich in solchen Fällen :

    [autoit]


    Adlibregister("Funktion",250)

    [/autoit]

    Hier können mehrere Funktionen registriert werden die dann auch Gleichzeitig ausgeführt werden. Bin mir aber was das gleichzeitige Ausführen angeht, auch nicht zu 100% sicher.

    :thumbup:

  • Meiner Erfahrung nach sind die Adlib Funktionen für Schleifendurchläufe eher ungeignet. Auch können sich die Timings, wenn mehrere Adlibs aktiv sind, durch die Ausführungszeit überlagern - und das kann Fehlverhalten auslösen.
    Die bessere Methode ist imho der klassische Schleifendurchlauf! Multithreading oder ähnliches wird auch nicht mit Adlibs erreicht werden können, sobald ein Adlib gestartet wird wird einfach ein Aussprung aus dem derzeitigen Programmcode gemacht. Ist fast vergleichbar mit der alten Gosub Funktion, nur mit Timer.

    Grüße!

  • Also ich habe jetzt relativ lange daran rumgebastelt, aber habe den dreh immer noch nicht raus.

    @Techmix : ich habe versucht, eine funktion über ifthen & einen timer zu verwenden. Ich wollte also, wenn X zeit abgelaufen ist, Befehl Y ausgeführt wird. Jedoch habe ich das mit dem timer überhaupt nicht begriffen. Ich verstehe nicht, wie ich dem ifthen befehl sage, dass wenn X zeit vorgangen ist, Funktion X ausgeführt werden soll - ohne das der rest des scripts während der vergehenden zeit nichts tut?

    Wenn das nicht der Weg war, den du im Kopf hattest, könntest du deinen Gedankengang von vorhin auch noch ein mal genauer erklären?


    @bobekos : das habe ich dann auch versucht. Nur dabei wird das script irgendwie nicht mal ausgeführt. Ich erstelle also Genügend Funktionen, um alle Befehle, die ich benötige, nutzen zu können. Dann erstelle ich eine Funktion, die per adlib all diese funktionen nutzen soll:

    Func _Start()
    AdlibRegister("Func1", 100)
    AdlibRegister("Func2", 100)
    AdlibRegister("Func3", 100)
    EndFunc

    Weise der obigen Funktion einen Hotkey zu, starte das Script, drücke ihn und dann passiert nichts. Obwohl die Funktionen sonst funktionieren, passiert hier nichts..


    Wenn es Sinnvoll ist, kann ich mein Script mal hier posten.

  • Also...
    Ich habe mal etwas geschrieben das vielleicht dein Problem löst oder erklären kann.

    [autoit]


    ; Timingvorgaben, in Sec
    Global _
    $i_Intervall1 = 3, _
    $i_Intervall2 = 5, _
    $i_Intervall3 = 10

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

    ; Timing-Handles
    Global _
    $h_Timer1 = TimerInit(), _
    $h_Timer2 = TimerInit(), _
    $h_Timer3 = TimerInit()

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

    ; Schleife
    While 1
    if TimerDiff($h_Timer1) >= $i_Intervall1 * 1000 Then ; Umrechnung von Ms in Sec
    Func1() ; Ausführung von Funktion
    $h_Timer1 = TimerInit() ; Timer zurücksetzen
    EndIf
    if TimerDiff($h_Timer2) >= $i_Intervall2 * 1000 Then
    Func2()
    $h_Timer2 = TimerInit()
    EndIf
    if TimerDiff($h_Timer3) >= $i_Intervall3 * 1000 Then
    Func3()
    $h_Timer3 = TimerInit()
    EndIf
    Sleep(50)
    WEnd

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

    ; Auszuführende Funktionen
    Func Func1()
    ; ...
    EndFunc
    Func Func2()
    ; ...
    EndFunc
    Func Func3()
    ; ...
    EndFunc

    [/autoit]

    Grüße!

  • Ihr werdet das bestimmt schrecklich finden :|
    Also erst mal das mit adlib ( weil ich das zuletzt ausporbiert habe :(

    HotKeySet("{F5}", "_Start")
    HotKeySet("{F6}", "TogglePause")
    HotKeySet("{F7}", "Terminate")
    $windowname = "Neues Textdokument"

    Func _Start()
    AdlibRegister("A", 3000)
    AdlibRegister("B", 5000)
    AdlibRegister("C", 7000)
    EndFunc

    Func A()
    ControlSend($windowname,"A")
    EndFunc

    Func B()
    Send($windowname,"B")
    EndFunc

    Func C()
    ControlSend($windowname,"C")
    EndFunc

    Func TogglePause()
    = Not paused
    While $paused
    sleep(100)
    WEnd
    EndFunc

    Func Terminate()
    Exit 0
    EndFunc

    Was das machen soll: alle 3000ms den text aus "A" schreiben, alle 5000ms den Text aus "B" schreiben & alle 7000ms den Text aus "C" schreiben.


    Und jetzt das mit dem timer, auch wenn das mittlerweile noch kaputter als vorher ist, weil ich so doof daran rumgebastelt hab:


    Global $Paused
    HotKeySet("{F5}", "TogglePause")
    HotKeySet("{F6}", "Terminate")
    $timer1 = TimerInit()
    $windowname = "Neues Textdokument"

    If <C> true, Then
    A
    Else
    While 1
    B
    Sleep(1000)
    WEnd
    EndIf

    Func A()
    ControlSend($windowname,"A")
    EndFunc

    Func B()
    ControlSend($windowname,"B")

    Func C()
    if($timer1 = 5000) Then
    return True
    Else
    return False
    EndIf
    EndFunc

    Func TogglePause()
    $Paused = Not $Paused
    While $Paused
    Sleep(100)
    WEnd
    EndFunc

    Func Terminate()
    Exit 0
    EndFunc

    Was das machen soll: alle 1000ms den Text aus "A" schreiben und alle 5000ms, wenn der Timer also rum ist, den Text aus "B"

  • Aller Anfang ist schwer ;)

    Grüße!

    [Edit]
    Lad dir die deutsche Hilfe runter, ist zwar nicht mehr aktuell aber die solltest du Lesen! Die habe ich auch nach 7 Jahren immer offen, weil man kann sich einfach nicht alles Merken ^^

  • Ansonsten sieh dir das mal an:

    [autoit]

    local $Timer[3]=[TimerInit(),TimerInit(),TimerInit()]
    while sleep(10)
    if TimerDiff($Timer[0])>5000 then
    ;...
    $Timer[0]=TimerInit()
    elseif TimerDiff($Timer[1])>7000 then
    ;...
    $Timer[1]=TimerInit()
    elseif TimerDiff($Timer[2])>9000 then
    ;...
    $Timer[2]=TimerInit()
    endif
    WEnd

    [/autoit]

    Geht natürlich nur, wenn das in den If-zweigen nicht länger als 2000ms dauert ;)

  • Ich habe jetzt praktisch (versucht) mein Script mit dem, was du geschrieben hast, ergänzt.

    Dann komm das:

    Error Line 7:

    Global $i_intervall 1 = 1.5.....
    (zählt alle intervalle auf)

    Error: No variable given for "Dim", "Local", "Global", "Struct" or "Const" statement.


    Habe 0 Ahnung, was das bedeutet. Tipps? Am besten nur Erklären was der Error bedeutet, ich würde das gern selbst gefixt bekommen :saint:

    Danke :D

    Edit: Ich hab doch unter F1 Hilfe. Oder meinst du eine andere?#

    Edit2: @Kanashius : hab ich versucht. Selber Error wie ^

    2 Mal editiert, zuletzt von Exgod (31. Oktober 2014 um 20:30)

  • Da sind keine Leerzeichen, sorry. Ich schreib mal exakt aus dem Error ab:

    Line 7 (File "C:\...)

    Global $i_Intervall1 = 1,5, $i_Intervall2 = 1,5, $i_Intervall3 =3, Global $i_Intervall1 = 1,^ERROR

    Error: No variable given for "Dim", "Local", "Global", "Struct" or "Const" statement.

    EDIT: hab mal die Striche raus genommen, also von:
    Global _
    $i_Intervall1 = 3, _
    $i_Intervall2 = 5, _
    $i_Intervall3 = 10

    nach

    Global
    $i_Intervall1 = 3,
    $i_Intervall2 = 5,
    $i_Intervall3 = 10

    dann kommt nur noch folgendes:

    Global
    Global^ERROR

    Error: No variable given for "Dim", "Local", "Global", "Struct" or "Const" stat

  • Ob ich Punkt oder Komma verwende ändert nichts daran, dass die Fehlermeldung kommt =/

    Habe tatsächlich beides ausprobiert :D Das ganze sieht jetzt so aus:
    Global
    $i_Intervall1 = 1.5,
    $i_Intervall2 = 1.5,
    $i_Intervall3 = 3,

  • Wenn du Variablen "untereinander" deklarieren willst, musst du anweisen das die Zeile nicht abgeschlossen ist (die Unterstriche). Sieh dir nochmal genau den Aufbau von meinem Script an!
    Und ja, ich meine die F1 Hilfe. Wenn diese auf Englisch ist, hast du dir nicht die deutsche runtergeladen.