Winform timer tick 안에서 enabled 제어

일을 하다가 새로운 곳에 입사하거나, 아니면 기존 소스를 보면서 재직자의 소스를 보다보면 가끔씩

private void TimerEvent_Tick(object sender, EventArgs e)
{
     TimerEvent.Enabled = false;

     // 타이머에서 작업할 내용

     TimerEvent.Enabled = true;
}

위와 같은 코드를 볼 수 있었고 실제로도 많이 쓰신다고 합니다.
어느 제작년쯤 윈폼으로 경력이 만 4년차가 되어가던 중에 의문이 들었는데
정말 tick 안에서 Enabled 제어를 하는게 의미가 있는가? 에 대한 것인데요.
나름대로 찾아보고 결론을 낸 것은 전혀 효과가 없다 였습니다.
2년전이라 잘 기억은 안나지만, 더듬어보면

.NET Framework 4.8 레퍼런스 소스를 기준으로 참고했을 때, winform timer는 단순히 WM_TIMER 메세지를 발생시키는 윈도우 이벤트이며, 메세지 큐는 윈도우 메세지를 큐형식으로 순차처리 하기 때문에 처리가 끝나지 않은 Tick이 또 발생할 수 없다

아래는 제 블로그에 제가 썼던 당시의 내용입니다.

물론 윈폼 타이머가 2개라서 동일한 Tick 이벤트가 각기 다른 타이머에 할당되어있는 경우라면야 모르겠지만, 타이머가 하나일 때 하나의 틱이 할당되어있다면, 타이머는 그 작업을 끝낸 후 Interval을 카운트 하여 Interval이 지나면 다시 그 Tick이 발생하는 것으로 이해했습니다.

나름대로 결론을 내고 정리해서 개인블로그에 아티클도 작성했었지만…블로그의 업데이트도 고려해야하기 때문에 다시 한 번 여쭤봅니다.

Winform Timer Tick 이벤트 내부에서 동기화 목적의 Enabled 프로퍼티의 제어는 의미가 있을까요?

좋아요 2

알고 계신 내용이 맞습니다. 동기화 목적으로 의미 없습니다. (참고로, 링크하신 글에서 Show Dialog가 메시지 큐를 새로 만든다고 적으셨는데, 메시지 루프를 새로 만드는 것일 뿐 큐는 새로 만들지 않습니다.)

좋아요 1

단지, 그 작업이 의미가 없다고 볼 수는 없습니다. 가령, (interval == 1초인 경우) timer tick 이벤트 안에서 1초가 넘는 처리 시간이 매번 걸린다고 가정했을 때, Enabled=true/false를 하지 않으면 해당 스레드는 Timer tick을 처리하는 데만 계속 할당이 되어 UI 반응성이 더 낮아집니다. 그나마 true/false를 번갈아 했으니 최소 1초 만이라도 다른 작업에 스레드가 처리할 수 있는 시간을 벌어주고 있는 것입니다.

감사합니다 kevin13님!
음…이 말씀은 1초가 넘는 작업을 처리할 경우 Tick이 처리되지 않더라도 새로운 Tick이 발생한다는 의미신가요? 아니면 Tick 처리중에 또 발생하지는 않지만, 마치 밀린 일거리를 처리하듯 Tick이 종료된 후 이미 interval은 1초가 초과한 상태니까 곧바로 Tick을 이어서 다시 발생시킨다는 의미인가요?

좋아요 1

새로운 Tick이 발생하는 것이 아니고, 새로운 WM_TIMER 메시지가 시스템에 의해서 메시지 큐에 넣어지는 것입니다. 단지, 이벤트에서도 낮은 우선 순위를 차지하기 때문에 UI와 관련된 메시지가 들어오면 그게 더 빨리 처리됩니다.

그리고, 일부 이벤트는 합쳐지는 식으로 처리됩니다. 가령 WM_PAINT의 경우 3개가 메시지 큐에 쌓여있으면 처음 2개는 무시하고 마지막 것을 하나 처리함으로써 repaint를 하는 식입니다. WM_TIMER도 동작 방식으로 봐서는 그런 식으로 처리하는 걸로 보입니다.

좋아요 1

아…그럼 일반적인 경우 메세지루프는 1개이기 때문에 Interval은 타이머가 동작하면서부터 때가되면 그때마다 메세지 큐에 WM_TIMER를 넣어줄뿐 결국 처리되는 것은 순차처리라 Tick은 한번씩만 발생이 된다는 것이군요. 결국 Tick안에서 Enabled를 제어하는 것은 메세지큐에 이벤트 메세지들을 쌓는 것을 잠시마나 막아줄 뿐, Tick 자체의 중복 발생을 막기 위해 사용하는 건 잘못알고 사용하는거구요. 이렇게 이해한게 맞을까요?

좋아요 1

찾아보니 아래의 글에서,

Can I force a WM_TIMER message to be generated when the timer comes due, even if the message queue is not idle? | The Old New Thing (microsoft.com)

WM_TIMER는 메시지 큐가 비어있어야만 추가된다고 합니다.

오…그러면 Enabled 제어는 의미가 없어지는게 맞군요… 언제나 정말 감사드립니다 kevin13님 !!

별도로 정리해 봤으니 참고하세요.

WM_TIMER의 동작 방식 개요
; Windows: 188. WM_TIMER의 동작 방식 개요

좋아요 2

정리 감사드립니다. 잘 보겠습니다!!