Wrapping StopWatch timing with a delegate or lambda?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Stopwatch is easy to use for one code block, but repetitive timing code quickly becomes inconsistent across a project. Wrapping timing in a delegate or lambda helper gives you a single place for formatting, error handling, and thresholds. This approach keeps business methods clean while still producing useful performance data.
Why a Wrapper Is Better Than Repeated Inline Timing
Inline timing code usually starts simple and then grows with logging, tags, and exception behavior.
Typical drift problems:
- one file logs milliseconds, another logs ticks
- some paths forget to stop timing after exceptions
- operation names are inconsistent and hard to aggregate
A wrapper removes those differences. Teams can then improve timing behavior centrally without editing every call site.
Synchronous Helper with Func<T>
A practical baseline is a generic method that times an operation and returns its result.
The finally block ensures metrics are emitted even when the operation throws.
Overload for Action
Many operations do not return values. Add an overload to avoid dummy return values.
This keeps call sites readable for side-effect-only methods.
Async Helper for Task and Task<T>
For network and I O workloads, timing wrappers should support async execution.
Avoid wrapping async code with .Result or .Wait(), because that can distort timings and block threads.
Threshold Logging to Reduce Noise
In high-throughput services, logging every operation can flood logs. Add a minimum threshold.
This keeps instrumentation useful without overwhelming observability systems.
Integrating with Structured Logging
Free-form strings are easy at first, but structured fields make analysis easier later. Instead of one message string, log fields such as operation name and elapsed time. This helps dashboards group and compare operations by name.
A simple pattern is to pass a logger delegate from your application layer, so the timer helper stays framework-agnostic.
Testing Timing Helpers
You usually do not test exact durations, since execution time varies by machine and load. Instead, test behavior:
- wrapper returns operation result
- wrapper logs once per invocation
- wrapper logs on exceptions
- threshold logic suppresses fast calls
These tests give confidence without brittle millisecond assertions.
Common Pitfalls
- Measuring very small code blocks and assuming nanosecond-level accuracy.
- Timing async operations with blocking calls.
- Forgetting
finally, which drops metrics on exceptions. - Using vague operation names that cannot be aggregated.
- Logging every call in hot paths without thresholds.
Summary
- Delegate and lambda wrappers make
Stopwatchinstrumentation consistent. - Use
finallyto ensure timing is captured for both success and failure. - Provide sync and async wrappers so all code paths follow one pattern.
- Add thresholds and structured logging for production-scale observability.
- Test behavior of the wrapper, not exact elapsed values.
Related reading
- Write a program to find 100 largest numbers out of an array of 1 billion numbers
- writing tfrecord with multithreading is not fast as expected
- Xcode 11 debugger is extremely slow - A known problem?
- Xcode 14 deprecates bitcode - but why?
- Write to Windows Application Event Log without event source registration
- WriteFile blocks writing from C client to C server via named pipe
- Xcode 6 with Swift super slow typing and autocompletion
- Xcode keeps building storyboard after each keystroke

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.