---
title: SAIF.Framework.CodeTimer business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.CodeTimer
reference_type: package
---

# SAIF.Framework.CodeTimer business rules

This page captures business rules enforced by this library.

## BR-001: A timer must not be started while already running

| Field | Value |
| --- | --- |
| **Statement** | A timer must not be started while it is already running. |
| **Trigger** | `CodeTimerEntry.Start()` is called on an entry whose internal `running` flag is already `true`. |
| **Enforcement** | `CodeTimerEntry.Start()` |
| **Outcome** | Throws `ApplicationException("StopWatch running")`. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerEntry.cs |

---

## BR-002: A timer must not be stopped while not running

| Field | Value |
| --- | --- |
| **Statement** | A timer must not be stopped while it is not running. |
| **Trigger** | `CodeTimerEntry.Stop(bool)` is called on an entry whose `running` flag is `false`. |
| **Enforcement** | `CodeTimerEntry.Stop(bool isFinal)` |
| **Outcome** | Throws `ApplicationException("StopWatch not running")`. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerEntry.cs |

---

## BR-003: Results cannot be requested while any timer is still active

| Field | Value |
| --- | --- |
| **Statement** | Results cannot be requested while any timer is still active. |
| **Trigger** | `CodeTimerResult.CreateItems()` iterates entries and finds one with `IsRunning() == true`. |
| **Enforcement** | `CodeTimerResult.CreateItems()` |
| **Outcome** | Throws `ApplicationException("Timer still executing.")`. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResult.cs |

---

## BR-004: Stopping a timer by key requires the key to already exist

| Field | Value |
| --- | --- |
| **Statement** | Stopping (or looking up) a timer by key requires the key to already exist in the data store. |
| **Trigger** | `CodeTimer.Stop(string name, bool isFinal)` is called with a key not present in `data`, while `Enabled` is `true`. |
| **Enforcement** | `CodeTimer.Stop(string, bool)` (private) |
| **Outcome** | Throws `ApplicationException("The key '{0}' does not exist")`. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimer.cs |

---

## BR-005: Timing is only recorded when both the global switch and any per-method attribute allow it

| Field | Value |
| --- | --- |
| **Statement** | Timing is only recorded when both the global enable switch and any per-method attribute allow it. |
| **Trigger** | Global: `CodeTimer.Enabled == true`. Per-method: a `CodeTimerAttribute` is present on the target `MethodBase` with `Enabled == true` (when using the `MethodBase`-based `Start`/`Stop` overloads); if no attribute is present, the attribute check is skipped and the call still proceeds via the private key-based `Start`. |
| **Enforcement** | `CodeTimer.Start(MethodBase, ...)` / `Stop(MethodBase, ...)`, private `Start(string)` |
| **Outcome** | When disabled, `Start` returns an empty key/no-op and `Stop` returns `null` without touching the data store. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimer.cs |

---

## BR-006: Result XML omits statistically insignificant attributes

| Field | Value |
| --- | --- |
| **Statement** | Result XML omits statistical attributes when they are not meaningful. |
| **Trigger** | An item's `Qty <= 1` (no shortest/longest/average/qty attributes emitted); an item's `Elapsed <= 0` (no `ms` attribute, and children are not recursed into); a span's computed milliseconds is `<= 0` (filtered out of `spans` output). |
| **Enforcement** | `CodeTimerResult.RecurseXml` |
| **Outcome** | Produces a compact XML tree that only reports statistically meaningful measurements. |
| **Source** | SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResult.cs |

## Notes
- All six rules above are enforced entirely within the compiled assembly; none involve database or SQL interactions, so the optional `Tables`/`SQL` fields are omitted from the per-rule tables.
- The orphaned WinForms viewer files (`CodeTimerModel.cs`, `CodeTimerResults.cs`, `CodeTimerResults.Designer.cs`) are excluded from the compiled project and therefore do not contribute any enforced business rules to this page.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

## Sources
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimer.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerEntry.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResult.cs
