This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
IntervalAction is a .NET library that provides a simple way to execute actions at specified intervals. It's a NuGet package that supports multiple .NET versions (netstandard2.0, netstandard2.1, net5.0-net9.0).
This project uses a custom ktsu.Sdk and a PowerShell-based build system (PSBuild) for CI/CD operations.
Build the solution:
dotnet build IntervalAction.slnRun all tests:
dotnet test IntervalAction.Test/IntervalAction.Test.csprojRun tests with detailed output:
dotnet test IntervalAction.Test/IntervalAction.Test.csproj --logger "console;verbosity=detailed"Restore dependencies:
dotnet restoreClean build artifacts:
dotnet cleanPack for NuGet:
dotnet pack IntervalAction/IntervalAction.csprojThe project uses GitHub Actions with a custom PowerShell module (PSBuild) located in scripts/PSBuild.psm1. The main workflow is .github/workflows/dotnet.yml which:
- Builds and tests the project
- Runs SonarQube analysis (if configured)
- Generates releases and publishes to NuGet
- Updates WinGet manifests
To manually run the PSBuild pipeline locally:
Import-Module ./scripts/PSBuild.psm1
# See the module for available functions-
IntervalAction (
IntervalAction/IntervalAction.cs): Main class that schedules and executes recurring actions- Uses a polling-based approach with configurable
PollingInterval - Manages action execution in separate tasks
- Thread-safe with lock-based synchronization
- Prevents overlapping executions
- Supports two interval types:
FromLastCompletion: Interval starts after action completesFromLastStart: Interval starts when action begins
- Uses a polling-based approach with configurable
-
IntervalActionOptions (
IntervalAction/IntervalActionOptions.cs): Configuration class containing:Action: The action to executeActionInterval: Time between executionsPollingInterval: How often to check if action should run (default 1 second)IntervalType: Timing measurement type (defaultFromLastCompletion)
-
IntervalType: Enum defining interval measurement strategies
- Factory Pattern: Static
Start()method creates and initializes instances - Polling Pattern: Background task continuously checks if action should run based on timing
- Task-Based: Uses .NET Tasks for asynchronous execution
- Lock-Based Synchronization: Uses
Lockclass for thread safety
- Actions execute in separate tasks to prevent blocking the polling loop
- Exception handling: Exceptions from actions are captured and can be rethrown via
RethrowExceptions() - The library prevents overlapping executions - if an action is still running when the next interval arrives, it waits until the current action completes
LastRunTimestamp(aStopwatchtimestamp) tracks when the action last executed (based onIntervalType), and is what scheduling measures from.LastRunTimerecords the same moment as wall-clock time for reporting only: the wall clock can be set back, which would hold the action off for as long as it moved- A run is due once
ActionIntervalhas passed (>=), and aFromLastStartrun is stamped with the clock reading its tick judged it due at, not when the thread pool started it. The polling wait topsTask.Delayup to the fullPollingInterval, because timers can wake a tick early. Without all three, equal polling and action intervals regularly skip a tick - Polling can be stopped/restarted via
Stop()/StopAsync()andRestart()/RestartAsync(). A dispatched run re-checksStopGenerationunder the lock before it begins, soStop()skips one that has not started;StopAsync()also waits for the polling loop and any run in progress - The class is sealed and implements
IDisposable.Dispose()stops likeStop()and marks the instance disposed, soRestart()/RestartAsync()throwObjectDisposedException. The polling loop roots the instance, so an instance that is neither stopped nor disposed runs for the life of the process
The test project uses MSTest with the Microsoft Testing Platform (MSTest.Sdk). Tests are located in IntervalAction.Test/IntervalActionTests.cs.
Test categories covered:
- Interval timing verification (FromLastCompletion, FromLastStart)
- Overlapping execution prevention
- Start/Stop/Restart lifecycle
- Exception handling
- Edge cases (zero interval, negative interval)
- Thread safety
To run a specific test:
dotnet test --filter "FullyQualifiedName~IntervalActionTests.ActionExecutesAfterIntervalFromLastCompletion"IntervalAction/
├── IntervalAction/ # Main library project
│ ├── IntervalAction.cs # Core implementation
│ ├── IntervalActionOptions.cs # Configuration classes
│ └── IntervalAction.csproj # Project file (uses ktsu.Sdk)
├── IntervalAction.Test/ # Test project
│ ├── IntervalActionTests.cs # Unit tests
│ └── IntervalAction.Test.csproj
├── scripts/ # Build and CI/CD scripts
│ └── PSBuild.psm1 # PowerShell build module
└── .github/workflows/ # GitHub Actions workflows
- Use explicit suppression attributes with justifications for warnings (not global suppressions)
- Make suppressions as targeted as possible
- Avoid preprocessor defines for suppressions unless necessary
- Root namespace:
ktsu.IntervalAction - Test namespace:
ktsu.IntervalAction.Test
The library has minimal external dependencies:
- Uses
Ensure.NotNull()for argument validation (likely from ktsu.Sdk) - Standard .NET libraries only (System.Threading.Tasks, etc.)