Praktische Erfahrung:
Gerade bei sehr kurzen Timerintervallen kann es passieren, dass das Ereignis bereits wieder ausgelöst wird, bevor das letzte Ereignis komplett verarbeitet wurde.
Aber nur, wenn da irgendwo ein Application.ProcessMessages im Spiel ist. Denn sonst kann ja niemand das WM_TIMER verarbeiten während man noch in der Messageloop hängt.
Am besten wäre jedenfalls vermutlich ein separater Thread, der sich zu den festgelegten Zeitpunkten mit dem Hauptthread synchronisiert und die gewünschte Aktion durchführt.
Dann belastet man die Messageloop nicht so stark und kann die Zeitpunkte auch genauer steuern.