cDelay vs Native Do...Loop + DoEvents and Timer Control Comparison
Fundamental Differences
Not exactly the same. cDelay provides a more complete and flexible delay mechanism, suitable for different scenario requirements.
Implementation Mechanism Comparison
| Method | Implementation | Blocking | CPU Usage |
|---|---|---|---|
| Native Do Loop | Pure loop occupies CPU, uses DoEvents to release control | Semi-blocking | High (loop always running) |
| Timer Control | Windows timer (SetTimer), requires manual shutdown | Non-blocking | Low |
| cDelay Event/Callback Mode | Windows timer (SetTimer), async callback | Non-blocking | Low (timer triggered by system) |
| cDelay Sync Mode | Message pump loop (PeekMessage) | Pseudo-blocking | Low (processes messages without freezing UI) |
cDelay Core Advantages
1. True Non-blocking (Event/Callback Mode)
Native approach - Code runs continuously, occupies CPU:
Do While Timer < target
DoEvents ' Releases control, but loop still running
LoopTimer Control approach - Requires manual management of enable/disable:
' Drag a Timer control onto the form at design time
Timer1.Interval = 3000
Timer1.Enabled = True
Private Sub Timer1_Timer()
Timer1.Enabled = False ' Must manually disable, otherwise repeats
MsgBox "Time's up!"
End SubcDelay Event Mode - Returns immediately after setting, triggers once automatically:
Delay.CountDown 3000 ' Returns immediately, triggers OnTime event after 3 seconds, auto cleanup2. Supports Callback Function Mode
Can directly call object methods and pass parameters:
' Chainable call, concise and elegant
Delay.Callback(Me, "UpdateUI", "param1", 123).CountDown 1000
' Compared to native approach requiring manual call after loop3. Precise Time Control
| Method | Precision |
|---|---|
Native Timer | ~50ms |
cDelay GetTickCount | 1ms level |
4. Cancellable Mechanism
' Cancel anytime
Delay.Cancel
' Sync mode can also check if cancelled
If Delay.IsCancelled Then
' User cancelled operation
End If5. More Complete Message Pump Processing
cDelay uses complete PeekMessage → TranslateMessage → DispatchMessage message processing chain, more reliable than simple DoEvents.
Timer Control vs cDelay Deep Comparison
Although Timer control is also based on Windows timer, it has obvious limitations compared to cDelay:
Timer Control Limitations
| Limitation | Description |
|---|---|
| Repeat Triggering | Timer triggers repeatedly by default, must manually set Enabled = False |
| No Built-in Callback | Can only handle via events, cannot directly call specified function |
| Hard to Pass Parameters | Needs to use global/module-level variables indirectly |
| Scattered Code | Initialization code and callback code are separated, poor readability |
| Lifecycle Management | Manual management, easy to forget shutdown causing repeated execution |
Code Comparison Example
Scenario: Execute specific task after 3 seconds with parameters
Timer Control Approach (Cumbersome)
' Module-level variables to store parameters
Private m_UserID As Long
Private m_Message As String
Private Sub btnStart_Click()
m_UserID = 123
m_Message = "Operation complete"
Timer1.Interval = 3000
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Timer1.Enabled = False ' Must manually disable!
ProcessResult m_UserID, m_Message ' Use stored parameters
End Sub
Private Sub ProcessResult(ByVal UserID As Long, ByVal Msg As String)
MsgBox "User " & UserID & ": " & Msg
End SubcDelay Callback Mode (Concise)
Private Sub btnStart_Click()
' One line, parameters passed directly, auto one-time execution
Delay.Callback(Me, "ProcessResult", 123, "Operation complete").CountDown 3000
End Sub
Public Sub ProcessResult(ByVal UserID As Long, ByVal Msg As String)
MsgBox "User " & UserID & ": " & Msg
End SubMulti-Task Scenario Comparison
Scenario: Execute multiple different delay tasks simultaneously
Timer Control Approach (Requires multiple controls or complex management)
' Need multiple Timer controls or complex single Timer state management
Timer1.Interval = 1000: Timer1.Enabled = True ' Task 1
Timer2.Interval = 2000: Timer2.Enabled = True ' Task 2
Timer3.Interval = 3000: Timer3.Enabled = True ' Task 3
' Or one Timer + complex state judgment...cDelay Approach (Instances are independent, more elegant and concise with future cDelays)
Private m_Delay1 As cDelay
Private m_Delay2 As cDelay
Private m_Delay3 As cDelay
Private Sub btnStart_Click()
Set m_Delay1 = New cDelay
Set m_Delay2 = New cDelay
Set m_Delay3 = New cDelay
m_Delay1.Callback(Me, "Task1").CountDown 1000
m_Delay2.Callback(Me, "Task2").CountDown 2000
m_Delay3.Callback(Me, "Task3").CountDown 3000
End SubCode Conciseness Comparison
Native Approach (Verbose)
Dim start As Long, cancelled As Boolean
start = GetTickCount()
Do While GetTickCount() < start + 3000
DoEvents
If UserClickedCancel Then
cancelled = True
Exit Do
End If
Loop
If Not cancelled Then Call DoSomethingcDelay Approach (Concise)
' Callback mode
Delay.Callback(Me, "DoSomething").CountDown 3000
' When cancellation needed: Delay.CancelUse Case Comparison
| Scenario | Recommended | Reason |
|---|---|---|
| Simple delay, temporary test | Native Do Loop | Simple and direct, no extra dependencies |
| Simple periodic task | Timer Control | Drag and drop directly on form designer |
| One-time delay + callback | cDelay Callback Mode | No manual shutdown, direct parameter passing |
| Still need to respond to user operations while waiting | cDelay Sync Mode | Message pump processing more complete |
| Need precise timing, cancellable | cDelay | 1ms precision + Cancel mechanism |
| Batch scheduling tasks | cDelay | Collection management, auto lifecycle |
| Multi-instance independent management | cDelay | Each instance independent, no conflicts |
Summary
| Dimension | Native Do Loop | Timer Control | cDelay |
|---|---|---|---|
| Usage | Code written directly | Form drag-drop | Create object instance |
| Complexity | Simple | Simple | Medium (wrapper class) |
| One-time Trigger | ✅ Natural support | ❌ Manual shutdown | ✅ Auto support |
| Built-in Callback | ❌ Not supported | ❌ Not supported | ✅ Supported |
| Parameter Passing | Direct | Need global variables | Direct (up to 9) |
| Cancel Mechanism | Exit Do | Enabled=False | Cancel method |
| Multi-instance | Single thread | Need multiple controls | Independent instances |
| Precision | 50ms | 55ms (system limit) | 1ms |
| CPU Usage | High | Low | Low |
| Lifecycle | Code controlled | Manual management | Auto management |
| Maintainability | Average | Average | Good |
| Scale | Temporary/simple | Simple timer tasks | Project-level/complex scheduling |
Selection Recommendations
| Your Requirement | Recommended Solution |
|---|---|
| Temporary test, a few lines搞定 | Native Do Loop + DoEvents |
| Simple periodic polling (like status check) | Timer Control |
| One-time delay then execute callback | cDelay Callback Mode |
| Need to pass parameters, precise control | cDelay |
| Multiple independent timer tasks | cDelay |
| Need sync wait but keep UI responsive | cDelay Sync Mode |
cDelay Core Value:
- ✅ One-time trigger (Timer requires manual shutdown)
- ✅ Direct callback parameter passing (No global variables needed)
- ✅ Independent instance management (Multi-tasks without conflicts)
- ✅ Auto lifecycle (No manual cleanup needed)
- ✅ 1ms precision + Cancel mechanism