SAIF.Framework.CodeTimer architecture¶
SAIF.Framework.CodeTimer is a lightweight, in-process, hierarchical code-timing/profiling utility exposed through a static CodeTimer façade. It captures named/method timing entries in process-wide static state and can render the results as an XDocument or to the console; it has no dependency on the SAIF BOF business-object framework and no web/UI layer in the compiled assembly.
Responsibilities¶
- Provide a static entry point (
CodeTimer) for starting, stopping, and resetting named or method-scoped timers, optionally organized in a hierarchical parent/child key structure. (CodeTimer.cs) - Gate timing collection through a global enable switch (
CodeTimer.Enabled) and an optional per-methodCodeTimerAttributeflag. (CodeTimer.cs,CodeTimerAttribute.cs) - Accumulate per-timer statistics (elapsed, shortest, longest, quantity, captured spans) in
CodeTimerEntryrecords held in a static dictionary. (CodeTimerEntry.cs) - Transform the flat,
;-delimited hierarchical key space into a tree ofCodeTimerItemnodes and serialize that tree to XML (CodeTimerResult.OutputXml) or console text (CodeTimerResult.OutputConsole). (CodeTimerResult.cs,CodeTimerItem.cs) - Provide a simple value type (
CustomTimeSpan) capturing one timed span's start/stop/duration, and a non-generic comparer (CodeTimerItemSorter) for ordering result items by name/elapsed/quantity/average. (CustomTimeSpan.cs,CodeTimerItemSorter.cs)
Component boundaries¶
CodeTimer(static class): public façade and sole externally visible responsibility of the library; owns the staticDictionary<string, CodeTimerEntry> datafield and coordinates start/stop/reset/results operations. (CodeTimer.cs)CodeTimerAttribute: method-level attribute type used purely as declarative metadata ([CodeTimer(enabled)]) read via reflection byCodeTimer; has no behavior of its own. (CodeTimerAttribute.cs)CodeTimerEntry: internal-mutation-state model for one timer (name, quantity, start/stop timestamps, longest/shortest/elapsed, span history);Start()/Stop()areinternal, so lifecycle control stays within the assembly. (CodeTimerEntry.cs)CodeTimerResult(internal class): reporting/transformation boundary — consumes the raw entry dictionary and produces theCodeTimerItemtree and its XML/console renderings; not part of the public surface. (CodeTimerResult.cs)CodeTimerItem: hierarchical result/data-transfer node used only for reporting output, not for live timing state. (CodeTimerItem.cs)CodeTimerItemSorter: supporting comparer boundary for orderingCodeTimerItemcollections; depends on the WinFormsSortOrderenum only, with no other WinForms coupling. (CodeTimerItemSorter.cs)CustomTimeSpan: minimal value holder for one timed interval, used insideCodeTimerEntry's span history and surfaced in XML output when requested. (CustomTimeSpan.cs)
Interaction model¶
- Callers invoke
CodeTimer.Start(MethodBase, ...)andCodeTimer.Stop(MethodBase, ...), which resolve a hierarchical key (viaGetCodeTimerParent) and, if gating checks pass, create/update aCodeTimerEntryin the staticdatadictionary. (CodeTimer.cs) CodeTimer.Reset()clearsdataentirely, andCodeTimer.Results()/Results(bool)hand the dictionary to an internalCodeTimerResult, which splits each hierarchical key on;(CreateItems) to build aCodeTimerItemtree, then serializes it viaOutputXml(orOutputConsole, reachable only by direct internal call, not through the publicCodeTimerAPI). (CodeTimer.cs,CodeTimerResult.cs)- All state is process-wide/AppDomain-wide static state on
CodeTimer, not scoped per request or thread, and there is no locking around access todata, so concurrent calls from multiple threads could race*. (CodeTimer.cs) - Gating is two-layered: the global
CodeTimer.Enabledfield is checked in the private key-basedStart(string)overload, and the per-methodCodeTimerAttribute.Enabledflag is checked (via reflection) in the publicMethodBase-basedStart/Stopoverloads. (CodeTimer.cs,CodeTimerAttribute.cs)
The following diagram shows high-level component interactions within the compiled assembly.
flowchart TD
Caller["Calling code<br>(instrumented methods)"] --> CT["CodeTimer<br>(static façade)"]
CT --> Attr["CodeTimerAttribute<br>(per-method gate, via reflection)"]
CT --> Data["Static Dictionary<string, CodeTimerEntry><br>(process-wide state)"]
Data --> Entry["CodeTimerEntry<br>(per-timer state)"]
Entry --> Span["CustomTimeSpan<br>(captured span history)"]
CT --> Result["CodeTimerResult<br>(internal, reporting)"]
Result --> Item["CodeTimerItem<br>(hierarchical result tree)"]
Item --> Sorter["CodeTimerItemSorter<br>(ordering)"]
Result --> XmlOut["XDocument output<br>(CodeTimer.Results)"]
Result --> ConsoleOut["Console output<br>(internal-only, not exposed via CodeTimer)"]
Sequence diagram¶
The following diagram shows the primary start/stop/results sequence for a timed method call.
sequenceDiagram
participant Caller
participant CodeTimer
participant CodeTimerEntry
participant CodeTimerResult
Caller->>CodeTimer: Start(MethodBase)
CodeTimer->>CodeTimer: Check Enabled and CodeTimerAttribute
CodeTimer->>CodeTimerEntry: Start()
Caller->>CodeTimer: Stop(MethodBase)
CodeTimer->>CodeTimerEntry: Stop(isFinal)
Caller->>CodeTimer: Results()
CodeTimer->>CodeTimerResult: new CodeTimerResult(data)
CodeTimerResult->>CodeTimerResult: CreateItems() / OutputXml()
CodeTimerResult-->>CodeTimer: XDocument
CodeTimer-->>Caller: XDocument (or null if no data)
Design constraints¶
- The compiled
SAIF.Framework.CodeTimer.csproj<Compile>item group includes onlyCodeTimer.cs,CodeTimerAttribute.cs,CodeTimerEntry.cs,CodeTimerItem.cs,CodeTimerItemSorter.cs,CodeTimerResult.cs,CustomTimeSpan.cs, andProperties\AssemblyInfo.cs. (SAIF.Framework.CodeTimer.csproj) CodeTimerModel.cs,CodeTimerResults.cs, andCodeTimerResults.Designer.csexist on disk in the same folder but are not referenced by any<Compile>element and are therefore excluded from the compiled project — they are orphaned/stale code, not active architecture. They implement a WinForms results viewer (CodeTimerResults : FormusingAga.Controls.Tree.TreeViewAdv) and a supportingITreeModeladapter (CodeTimerModel), and they reference members (entry.sw,entry.timesstarted, a differently-shapedCodeTimerItemconstructor,CodeTimeritemschildren) that do not exist on the current, compiledCodeTimerEntry/CodeTimerItemclasses, indicating they would not compile if re-added to the project**. (CodeTimerModel.cs,CodeTimerResults.cs,CodeTimerResults.Designer.cs)- Because the WinForms viewer files are excluded from the build, the vendored
Aga.Controlstree-view control library is an unused dependency relative to the built assembly — it is referenced only by the orphaned files, not by any compiled type. (CodeTimerModel.cs,CodeTimerResults.cs) - The one live-code call site for the WinForms viewer,
(new CodeTimerResults(data)).ShowDialog();inCodeTimer.cs, is commented out and therefore excluded from active behavior. (CodeTimer.cs) System.Windows.Formsremains a referenced framework assembly for the compiled project solely for theSortOrderenum used byCodeTimerItemSorter; no live UI/Form code is compiled into the assembly. (CodeTimerItemSorter.cs)- All timer state is process-wide/AppDomain-wide static state with no synchronization, so the library is not safe for concurrent multi-threaded timer usage without external coordination*. (
CodeTimer.cs) - The library does not inherit from or reference any SAIF BOF business-object framework types (
clsBusinessBase,clsBusinessCollectionBase,IBusinessCriteria), and has no ASP.NET/web layer.
Related documentation¶
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
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\CodeTimerItem.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerItemSorter.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResult.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CustomTimeSpan.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerModel.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResults.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\CodeTimerResults.Designer.cs
- SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer\SAIF.Framework.CodeTimer.csproj