SetTimer

Registriert eine Funktion, die automatisch und wiederholt in einem bestimmten Zeitintervall aufgerufen wird.

SetTimer Funktion, Periode, Priorität

Parameter

Funktion

Typ: Funktionsobjekt

Ein Funktionsobjekt, das aufgerufen werden soll.

Das Skript hinterlegt in seiner Liste von Timern eine Referenz zum Funktionsobjekt, die erst freigegeben wird, wenn der Timer gelöscht wird. Dies geschieht automatisch für einmalig laufende Timer oder kann durch Aufruf von SetTimer mit einer Periode von 0 erzwungen werden.

Wenn Funktion weggelassen wird, wird SetTimer mit dem Timer arbeiten, der den aktuellen Thread gestartet hat, sofern vorhanden. Zum Beispiel kann SetTimer , 0 innerhalb einer Timer-Funktion verwendet werden, um den Timer zum Löschen zu markieren, während SetTimer , 1000 die Periode des aktuellen Timers aktualisiert.

Hinweis: Die Übergabe einer leeren Variable oder eines Ausdrucks, der einen leeren Wert zurückgibt, wird als Fehler gewertet. Dieser Parameter muss entweder einen nicht-leeren Wert enthalten oder ganz weggelassen werden.

Periode

Typ: Integer

Wenn weggelassen und der Timer nicht existiert, wird er mit einer Periode von 250 erstellt. Wenn weggelassen und der Timer bereits existiert, wird er auf seine frühere Periode zurückgesetzt, sofern keine Priorität angegeben ist. Andernfalls wird der Absolutwert dieses Parameters als ungefähre Zeit in Millisekunden verwendet, die ablaufen muss, bevor der Timer ausgeführt wird. Der Timer wird automatisch zurückgesetzt. Er kann so eingestellt werden, dass er sich automatisch wiederholt oder nur einmal ausgeführt wird:

Der Absolutwert von Periode darf nicht größer als 4294967295 ms (49,7 Tage) sein.

Priorität

Typ: Integer

Wenn weggelassen, wird standardmäßig 0 verwendet. Andernfalls geben Sie einen Integer zwischen -2147483648 und 2147483647 (oder einen Ausdruck) an, um die Thread-Priorität des Timers zu bestimmen. Einzelheiten finden Sie unter Threads.

Um die Priorität eines existierenden Timers zu ändern, ohne ihn anderweitig zu beeinflussen, lassen Sie Periode weg.

Bemerkungen

Timer sind nützlich, weil sie asynchron laufen, d.h. sie werden in einem bestimmten Intervall (Frequenz) ausgeführt, egal ob das Skript gerade auf ein Fenster wartet, ein Dialogfenster anzeigt oder mit einer anderen Aufgabe beschäftigt ist. Timer können u.a. verwendet werden, um eine Aktion während der Abwesenheit des Benutzers auszuführen (in Verbindung mit A_TimeIdle) oder um unerwünschte Fenster sofort wieder zu schließen, wenn sie erscheinen.

Timer erzeugen nur die Illusion, als könne das Skript mehr als eine Aufgabe gleichzeitig ausführen. In Wirklichkeit werden zeitgesteuerte Funktionen genauso wie andere Threads behandelt: Sie können andere Threads, wie z.B. Hotkey-Subroutinen, unterbrechen oder von ihnen unterbrochen werden. Einzelheiten finden Sie unter Threads.

Jedes Mal, wenn ein Timer erstellt oder mit einer neuen Periode aktualisiert wird, wird seine Funktion nicht sofort aufgerufen; seine Periode muss zuerst ablaufen. Wenn die erste Ausführung des Timers sofort erfolgen soll, rufen Sie seine Funktion direkt auf (dabei wird allerdings kein neuer Thread gestartet, wie es der Timer selbst tut, d.h. Einstellungen wie SendMode verwenden zunächst nicht ihre Standardwerte).

Zurücksetzen: Wenn SetTimer auf einen bereits existierenden Timer angewendet wird, wird der Timer zurückgesetzt (es sei denn, es wurde Priorität angegeben und Periode weggelassen), d.h. seine Periode muss einmal komplett ablaufen, bevor seine Funktion erneut aufgerufen wird.

Genauigkeit des Timers: Durch die Granularität (Ungenauigkeit) der Zeiterfassung im Betriebssystem wird Periode möglicherweise auf das nächstmögliche Vielfache von 10 oder 15.6 Millisekunden aufgerundet (abhängig vom Typ der installierten Hardware und Treiber). Eine kürzere Verzögerung kann mit Loop+Sleep erreicht werden, wie bei DllCall+timeBeginPeriod+Sleep gezeigt.

Zuverlässigkeit: Es ist möglich, dass ein Timer nicht zum erwarteten Zeitpunkt ausgeführt wird, wenn die folgenden Bedingungen zutreffen:

  1. Andere Anwendungen belasten die CPU ziemlich stark.
  2. Die Funktion des Timers läuft noch nach erneutem Ablauf der Timer-Periode.
  3. Es gibt zu viele konkurrierende Timer.
  4. Der Timer wurde von einem anderen Thread unterbrochen, z.B. von einer anderen zeitgesteuerten Funktion, einer Hotkey-Subroutine oder einem benutzerdefinierten Menüpunkt (dies kann mit Critical verhindert werden). Wenn dies der Fall ist und der unterbrechende Thread lange Zeit zum Beenden braucht, wird der unterbrochene Timer für die Dauer der Unterbrechung deaktiviert. Alle anderen Timer laufen jedoch weiter, indem sie den Thread unterbrechen, der den ersten Timer unterbrochen hat.
  5. Das Skript ist durch Critical oder Thread Interrupt/Priority unterbrechungsfrei. Während dieser Zeit werden Timer nicht ausgeführt. Später, wenn das Skript wieder unterbrechbar ist, wird jeder überfällige Timer einmal so schnell wie möglich ausgeführt und dann wie geplant fortgesetzt.

Obwohl Timer auch laufen, wenn das Skript suspendiert ist, werden sie nicht ausgeführt, wenn Thread NoTimers für den aktuellen Thread wirksam ist oder wenn ein beliebiger Thread pausiert wird. Außerdem werden sie nicht ausgeführt, wenn der Benutzer durch eines der Menüs des Skripts navigiert (z.B. das Tray-Symbol-Menü oder eine Menüleiste).

Da Timer die laufende Skriptaktivität vorübergehend unterbrechen, sollten ihre Funktionen kurz gehalten werden (so dass sie schnell zum Abschluss kommen), wenn eine lange Unterbrechung unerwünscht ist.

Sonstige Bemerkungen: Ein temporärer Timer deaktiviert sich oft selbst durch seine eigene Funktion (siehe Beispiele weiter unten).

Jede via SetTimer aufgerufene Funktion verwendet vorerst die Standardwerte von Einstellungen wie SendMode. Diese Standardwerte können während der Startphase des Skripts geändert werden.

Wenn die Hotkey-Reaktionszeit von entscheidender Bedeutung ist (z.B. in Videospielen) und Timer im Skript enthalten sind, deren Funktionen länger als 5 ms zum Ausführen benötigen, verwenden Sie die folgende Funktion, um eine mögliche Verzögerung von 15 ms zu vermeiden. Eine solche Verzögerung würde sonst auftreten, wenn ein Hotkey genau dann gedrückt wird, wenn sich ein Timer-Thread in seiner unterbrechungsfreien Phase befindet:

Thread "Interrupt", 0  ; Macht alle Threads jederzeit unterbrechbar.

Wenn ein Timer deaktiviert wird, während seine Funktion gerade läuft, wird diese Funktion fertig ausgeführt.

KeyHistory zeigt an, wie viele Timer es gibt und wie viele gerade aktiv sind.

Threads, Thread (Funktion), Critical, Funktionsobjekte

Beispiele

Schließt unerwünschte Fenster, sobald sie erscheinen.

SetTimer MailWarnungenSchließen, 250

MailWarnungenSchließen()
{
    WinClose "Microsoft Outlook", "Während der Kommunikation mit dem Server wurde das Zeitlimit überschritten"
    WinClose "Microsoft Outlook", "Es konnte keine Verbindung aufgebaut werden"
}

Wartet auf ein bestimmtes Fenster und alarmiert dann den Benutzer.

SetTimer Alarm1, 500

Alarm1()
{
    if not WinExist("Videokonvertierung", "Prozess abgeschlossen")
        return
    ; Andernfalls:
    SetTimer , 0  ; d.h. der Timer deaktiviert sich selbst.
    MsgBox "Die Videokonvertierung wurde abgeschlossen."
}

Erkennt, ob ein Hotkey einmal, zweimal oder dreimal gedrückt wurde. Dadurch kann ein Hotkey eine andere Aktion ausführen, je nachdem, wie oft er gedrückt wurde.

#c::
TasteWinC(ThisHotkey)  ; Das ist ein benannter Funktions-Hotkey.
{
    static winc_eingaben := 0
    if winc_eingaben > 0 ; SetTimer bereits gestartet, also stattdessen den Tastendruck protokollieren.
    {
        winc_eingaben += 1
        return
    }
    ; Andernfalls ist das der erste Tastendruck einer neuen Serie. Zählung wird
    ; auf 1 gesetzt und der Timer gestartet:
    winc_eingaben := 1
    SetTimer Nach400, -400 ; Auf weitere Eingaben innerhalb von 400 ms warten.

    Nach400()  ; Das ist eine verschachtelte Funktion.
    {
        if winc_eingaben = 1 ; Die Taste wurde einmal gedrückt.
        {
            Run "m:\"  ; Einen Ordner öffnen.
        }
        else if winc_eingaben = 2 ; Die Taste wurde zweimal gedrückt.
        {
            Run "m:\multimedia"  ; Einen anderen Ordner öffnen.
        }
        else if winc_eingaben > 2
        {
            MsgBox "Drei oder mehr Klicks erkannt."
        }
        ; Egal welche obige Aktion ausgelöst wurde, Zählung zurücksetzen,
        ; um die nächste Serie von Tastendrücken vorzubereiten:
        winc_eingaben := 0
    }
}

Verwendet eine Methode als Timer-Funktion.

counter := SecondCounter()
counter.Start
Sleep 5000
counter.Stop
Sleep 2000

; Eine Beispielklasse zum Zählen von Sekunden...
class SecondCounter {
    __New() {
        this.interval := 1000
        this.count := 0
        ; Tick() hat einen impliziten Parameter "this", der eine Referenz auf
        ; das Objekt ist, daher müssen wir eine Funktion erstellen, die
        ; "this" und die aufzurufende Methode voneinander trennt:
        this.timer := ObjBindMethod(this, "Tick")
    }
    Start() {
        SetTimer this.timer, this.interval
        ToolTip "Zähler gestartet"
    }
    Stop() {
        ; Um den Timer zu deaktivieren, dasselbe Objekt erneut übergeben:
        SetTimer this.timer, 0
        ToolTip "Zähler ist bei " this.count " gestoppt"
    }
    ; In diesem Beispiel ruft der Timer diese Methode auf:
    Tick() {
        ToolTip ++this.count
    }
}

Tipps zum obigen Beispiel: