Skip to content

Stop a timed operation

This operation closes a running timer entry, rolls the interval that just elapsed into the entry's cumulative statistics, and returns the updated record to the caller. It mirrors the name and hierarchy resolution performed by the start operation so that a Stop call always lands on the exact same dictionary entry its matching Start call created or resumed.

Field Value
Operation ID CT-OP-002
Trigger Caller invokes CodeTimer.Stop(MethodBase...)
Inputs MethodBase method, optional customName, optional parentTimerKey
Outputs Updated CodeTimerEntry, or null when the stop call is gated off
Primary components CodeTimer.Stop, CodeTimer.GetCodeTimerParent, CodeTimerEntry.Stop, CustomTimeSpan.CustomTimeSpan
Entry point SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimer.cs

Steps

  1. Rebuild the method timer name using the same rule the start path uses, including the optional .{customName} suffix, so the name computed here is guaranteed to match the name computed at start time.
  2. Inspect the target method for CodeTimerAttribute, the same per-method gate the start path checks.
  3. If no attribute is present, return null immediately and leave the timer store untouched (BR-005).
  4. If the attribute exists but its Enabled flag is false, also return null without touching timer state (BR-005).
  5. Rebuild the same hierarchical key the corresponding start call produced, so the stop request addresses the correct dictionary entry rather than a namesake at a different nesting level.
  6. Evaluate the global CodeTimer.Enabled switch.
  7. If the switch is false, return null without updating any timer entry, mirroring the start path's behavior when timing is globally suppressed (BR-005).
  8. Require the composite key to already exist in the static data dictionary.
  9. On failure: if the key is missing — for example, Stop was called without a matching prior Start — throw the missing-key exception defined by BR-004 rather than silently creating an entry.
  10. Call CodeTimerEntry.Stop(true) on the matching entry to close out the current run.
  11. On failure: if the entry is not currently marked running — for example, Stop was called twice in a row for the same key — throw under BR-002.
  12. On success: stamp lastStopped with the current time, compute diff = lastStopped - lastStarted, add that duration into the entry's cumulative elapsed total, append a new CustomTimeSpan capturing this individual run, update longest and shortest if the new span exceeds or undercuts the prior extremes, and clear the entry's running flag so a subsequent Start can resume it.
  13. Return the updated CodeTimerEntry to the caller, now reflecting the just-completed interval in its counters and span history.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Stop request]) --> Resolve[Resolve method and custom name]
    Resolve --> Attr{Attribute present<br>and enabled?}
    Attr -->|No| NoOp([Return null])
    Attr -->|Yes| BuildKey[Build hierarchical key]
    BuildKey --> Enabled{CodeTimer.Enabled?}
    Enabled -->|No| Disabled([Return null])
    Enabled -->|Yes| Exists{Key exists?}
    Exists -->|No| Missing([Throw missing-key exception])
    Exists -->|Yes| Running{Entry running?}
    Running -->|No| NotRunning([Throw not-running exception])
    Running -->|Yes| Update[Record span and totals]
    Update --> EndOk([Return CodeTimerEntry])

Failure and edge-case behavior

  • A method with no CodeTimerAttribute produces no stop action at all and simply returns null, the same "opt-out" behavior as the start path.
  • Stopping a key that was never started — or was already reset — throws under BR-004 instead of returning null or creating a placeholder entry.
  • Stopping an entry that is not currently running, such as a duplicate stop call, throws under BR-002 rather than being treated as a harmless no-op.

Sources

  • SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimer.cs
  • SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerAttribute.cs
  • SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerEntry.cs
  • SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CustomTimeSpan.cs