SetTimer

서브루틴이 자동으로 그리고 반복적으로 지정된 시간 간격마다 기동되도록 만듭니다.

SetTimer , Label, PeriodOnOffDelete, Priority

매개변수

Label

점프해 갈 라벨 또는 핫키 라벨의 이름. Return이나 Exit을 만날 때까지 Label 아래의 명령어들이 실행됩니다. 거의 모든 다른 명령어의 매개변수처럼, Label변수 참조가 될 수 있습니다. %MyLabel%와 같이, 변수에 저장된 이름이 목표로 사용됩니다.

[v1.1.01+]: Label이 생략되면, A_ThisLabel이 사용됩니다. For example, SetTimer,, Off can be used inside a timer subroutine to turn off the timer, while SetTimer,, 1000 would either update the current timer's Period or set a new timer using the label which is currently running. [v1.1.24+]: If A_ThisLabel is empty but the current thread was launched by a timer, that timer is used. This is useful for timers which launch functions or function objects.

[v1.1.20+]: If not a valid label name, this parameter can be the name of a function whose parameter list has no mandatory parameters (see the function example), or a single variable reference containing a function object. For example, SetTimer %FuncObj%, 1000 or SetTimer % FuncObj, 1000. 함수 객체를 돌려주는 다른 표현식은 현재 지원하지 않습니다. See the class example for more details.

Note: [v1.1.24+]: Passing an empty variable or an expression which results in an empty value is considered an error. This parameter must be either given a non-empty value or completely omitted.

PeriodOnOffDelete

On: 이전 기간(period) 동안 비활성화되어 있던 타이머를 재활성화합니다. 타이머가 존재하지 않으면, 새로 만듭니다 (기본 간격은 250입니다). The timer is also reset. 타이머가 존재하지만 이전에 한-번만- 실행 모드로 설정되어 있었다면, 다시 한 번만 실행됩니다.

Off: 기존의 타이머를 끕니다.

Delete [v1.1.20+]: 기존의 타이머를 끄고 삭제합니다. 타이머가 함수 객체에 연관되어 있다면, 그 객체는 해제됩니다. 타이머를 끄더라도 객체는 해제되지 않습니다.

Period: Creates or updates a timer using the absolute value of this parameter as the approximate number of milliseconds that must pass before the timer is executed. The timer will be automatically enabled and reset. It can be set to repeat automatically or run only once:

Period는 정수여야 합니다. 단 변수나 표현식이 사용되면 안됩니다. Its absolute value must be no larger than 4294967295 ms (49.7 days).

Default: 이 경우는 소수점 이하는 전부 무시됩니다. 이 매개변수가 비어 있고 그리고:
1) 타이머가 존재하지 않는다면: 기간을 250으로 하여 생성됩니다.
2) 타이머가 이미 존재한다면: 그 타이머가 활성화되고 Priority를 지정하지 않는 한, 이전의 기간(period)은 리셋됩니다.

Priority

이 선택적 매개변수는 -2147483648에서 2147483647 사이의 정수입니다 (또는 표현식). 이 타이머의 쓰레드 우선 순위를 지정합니다. 생략하면, 0이 사용됩니다. 자세한 것은 쓰레드를 참조하십시오.

다른 것은 전혀 건드리지 않은 채로 기존 타이머의 우선 순위만 바꾸려면, 이 매개변수 앞의 매개변수를 빈 채로 두십시오.

논평

타이머는 비동기적으로 실행되기 때문에 유용합니다. 지정된 간격으로 일정하게 실행된다는 뜻입니다. 심지어 스크립트가 창을 기다리거나, 대화상자를 보여주거나 또는 다른 일을 하느라 바쁜 때에도 상관이 없습니다. 많이 사용되는 예로는 사용자가 쉴 때 어떤 일을 하기 (A_TimeIdle에 반영됨) 또는 사용자가 나타나는 순간 원하지 않는 창을 닫기가 있습니다.

타이머 때문에 스크립트가 동시에 여러 일을 수행한다는 환상을 불러 일으키지만, 사실은 그렇지 않습니다. 대신에, 시간제한 서브루틴을 다른 쓰레드와 똑같이 취급합니다: 핫키 서브루틴과 마찬가지로, 다른 쓰레드에게 인터럽트 당하고 또 인터럽트 할 수 있습니다. 자세한 것은 쓰레드를 참조하십시오.

타이머가 만들어질 때마다, 재활성되고, 새 기간(period)으로 갱신됩니다. 그의 서브루틴은 즉시 실행되지 않습니다; 먼저 기간(period)이 다해야 합니다. 타이머를 시작하자 마자 바로 실행하고 싶으면, Gosub를 사용해 타이머의 서브루틴을 실행하십시오 (그렇지만, 이것은 타이머 자체가 그런 것 처럼 새 쓰레드를 시작하지 않습니다; 그래서 SendMode와 같은 설정은 기본값으로 시작하지 않습니다).

Reset: If SetTimer is used on an existing timer and parameter #2 is a number or the word ON (or it is omitted), the timer is reset; in other words, the entirety of its period must elapse before its subroutine will run again.

타이머의 정밀도: OS의 시간-유지 시스템의 정밀도 때문에, Period는 전형적으로 (설치된 하드웨어와 드라이버의 유형에 따라) 가장 가까운 10 또는 15.6 밀리초의 배수로 반올림됩니다. 예를 들어, 1부터 10 (포함) 사이의 Period는 보통 Windows 2000/XP에서 10 또는 15.6과 동등합니다. 더 짧은 지연은 Loop+Sleep을 통하여 달성할 수 있습니다. 예제는 DllCall+timeBeginPeriod+Sleep를 보십시오.

신뢰성: A timer might not be able to run at the expected time under the following conditions:

  1. 다른 어플리케이션들이 CPU에 아주 큰 부담을 줍니다.
  2. The timer subroutine itself is still running when the timer period expires, or there are too many other competing timers (altering SetBatchLines may help).
  3. 타이머가 다른 쓰레드에 의해 인터럽트 되었습니다. 즉, 또다른 일정의 서브루틴, 핫키 서브루틴, 또는 맞춤 메뉴 항목이 타이머를 인터럽트 했습니다 (인터럽트는 Critical을 통하여 피할 수 있습니다). 이런 일이 일어나면 그리고 인터럽트한 쓰레드가 종료에 시간이 오래 걸린다면, 인터럽트된 타이머는 그 동안 꺼지는 효과가 있습니다. 그렇지만, 다른 타이머들은 계속해서 실행됩니다. 첫 번째 타이머를 인터럽트한 쓰레드를 또 인터럽트 합니다.
  4. Critical이나 Thread Interrupt/Priority의 결과로 스크립트를 인터럽트 할 수 없습니다. 그 시간 동안, 타이머는 실행되지 않습니다. 나중에, 스크립트가 다시 인터럽트가 가능해지면, 기간을 넘긴 타이머는 가능하면 한 번 빨리 실행된 다음, 그의 원래 일정을 재개합니다.

타이머는 스크립트가 보류중(suspended)일 때에도 작동합니다. 그러나 현재 쓰레드에 "Thread NoTimers"가 작용하고 있거나 어떤 쓰레드이든 쓰레드가 정지(paused)되어 있으면 작동하지 않습니다. 게다가, 사용자가 (예를 들어 트레이 아이콘 메뉴나 메뉴 바와 같은) 스크립트 매뉴를 통하여 항해하고 있을 때에도 작동하지 않습니다.

타이머는 임시로 스크립트의 현재 활동을 인터럽트해 작동하기 때문에, 그의 서브루틴은 (빨리 끝낼 수 있도록) 짧게 유지해야 합니다. 오랫 동안 인터럽트 하는 것은 바람직하지 못합니다.

Other remarks: 스크립트가 실행되는 중에도 효과를 유지하는 타이머는 보통 자동-실행 섹션에 만들어야 합니다. 대조적으로, 임시 타이머는 종종 그의 서브루틴에 의하여 꺼지기도 합니다 (이 페이지 하단의 예제를 보십시오).

시간제한 서브루틴이 실행 중일 때마다, SendMode와 같은 설정에 대한 기본 값으로 새롭게 시작합니다. 이런 기본 값은 자동-실행 섹션에서 바꿀 수 있습니다.

핫키의 반응 시간이 중요하다면 (게임에서와 같이) 그리고 스크립트가 보유한 타이머의 서브루틴이 실행에 대략 5 ms 이상이 걸려야 한다면, 다음 명령어를 사용해 15 ms 지연 시간으로 바꾸지 않도록 막습니다. 그렇게 하지 않으면 타이머 쓰레드를 인터럽트할 수 없는 순간에 핫키가 눌리면 그런 지연이 일어납니다:

Thread, interrupt, 0  ; 모든 쓰레드를 언제나 인터럽트가 가능하도록 만듭니다.

그의 서브루틴이 현재 실행 중인데 타이머가 꺼지더라도, 그 서브루틴은 완료할 때까지 계속 진행됩니다.

KeyHistory 특징은 얼마나 많은 타이머가 존재하는지 그리고 얼마나 많이 현재 켜져 있는지 보여줍니다.

스크립트를 계속 실행하려면 -- 오직 타이머만 담고 있는 스크립트 -- #Persistent를 사용하십시오.

Gosub, Return, Threads, Thread (command), Critical, IsLabel(), Menu, #Persistent

예제

원하지 않는 창이 나타날 때마다 닫습니다.

#Persistent
SetTimer, CloseMailWarnings, 250
return

CloseMailWarnings:
WinClose, Microsoft Outlook, 통신하는 동안 시간제한이 일어남
WinClose, Microsoft Outlook, 서버에 접속을 확립할 수 없었음
return

어떤 창이 나타나기를 기다렸다가 사용자에게 알려줍니다.

#Persistent
SetTimer, Alert1, 500
return

Alert1:
if not WinExist("Video Conversion", "Process Complete")
    return
; 그렇지 않으면:
SetTimer, Alert1, Off  ; 즉, 타이머는 여기에서 자신을 끕니다.
SplashTextOn, , , 비디오 변환이 끝났습니다.
Sleep, 3000
SplashTextOff
return

핫키가 한 번, 두 번, 그리고 세 번 눌렸는지 탐지합니다. 얼마나 많이 눌렀는가에 따라 핫키가 다른 조치를 수행할 수 있습니다.

#c::
if (winc_presses > 0) ; SetTimer가 이미 시작되었습니다. 그래서 대신에 키눌림을 기록합니다.
{
    winc_presses += 1
    return
}
; 그렇지 않으면, 이 번에 처음으로 키를 눌렀습니다.
;  카운트를 1로 설정하고 타이머를 시작합니다:
winc_presses := 1
SetTimer, KeyWinC, -400 ; 400 밀리초 창 안에서 키눌림을 기다립니다.
return

KeyWinC:
if (winc_presses = 1) ; 키가 한 번 눌렸습니다.
{
    Run, m:\  ; 폴더를 엽니다.
}
else if (winc_presses = 2) ; 키가 두 번 눌렸습니다.
{
    Run, m:\multimedia  ; 다른 폴더를 엽니다.
}
else if (winc_presses > 2)
{
    MsgBox, 세 번 이상 클릭이 탐지되었습니다.
}
; 위에서 어느 조치가 촉발되든 상관없이, 카운트를 리셋해
; 다음 키눌림을 준비합니다:
winc_presses := 0
return

A simple counter. Uses a function as the timer subroutine.

#Persistent
SetTimer, Tick, 1000

Tick()
{
    static count := 0
    ToolTip % count++
}

A more complex counter. Uses a method as the timer subroutine.

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

; An example class for counting the seconds...
class SecondCounter {
    __New() {
        this.interval := 1000
        this.count := 0
        ; Tick() has an implicit parameter "this" which is a reference to
        ; the object, so we need to create a function which encapsulates
        ; "this" and the method to call:
        this.timer := ObjBindMethod(this, "Tick")
    }
    Start() {
        ; Known limitation: SetTimer requires a plain variable reference.
        timer := this.timer
        SetTimer % timer, % this.interval
        ToolTip % "Counter started"
    }
    Stop() {
        ; To turn off the timer, we must pass the same object as before:
        timer := this.timer
        SetTimer % timer, Off
        ToolTip % "Counter stopped at " this.count
    }
    ; In this example, the timer calls this method:
    Tick() {
        ToolTip % ++this.count
    }
}

Tips relating to the above example: