diff --git a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerCSharp.csproj b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerCSharp.csproj
index 91b464afea..dfb40caafc 100644
--- a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerCSharp.csproj
+++ b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerCSharp.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net10.0
enable
enable
diff --git a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerMethods.cs b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerMethods.cs
index 3d5aff4106..6466bda710 100644
--- a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerMethods.cs
+++ b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/PeriodicTimerMethods.cs
@@ -46,7 +46,7 @@ private async Task RandomArrayTimerAsync()
Console.WriteLine(item);
}
- Console.WriteLine($"Created {numberOfArrays++} arrays in {stopWatch.Elapsed.Seconds}s");
+ Console.WriteLine($"Created {numberOfArrays++} arrays in {stopWatch.Elapsed.TotalSeconds:F1}s");
Console.WriteLine(DateTime.Now.ToString("O"));
}
}
@@ -65,6 +65,7 @@ public async Task StopTaskAsync()
_cancellationToken.Cancel();
await _task;
_cancellationToken.Dispose();
+ _periodicTimer.Dispose();
Console.WriteLine("The array task was canceled");
}
}
\ No newline at end of file
diff --git a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/Program.cs b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/Program.cs
index 97686b45ef..d87920a7b6 100644
--- a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/Program.cs
+++ b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharp/Program.cs
@@ -6,7 +6,7 @@
var timerTask = new PeriodicTimerMethods(TimeSpan.FromSeconds(1), numOfElements);
timerTask.Start();
-Console.WriteLine("Press any button to terminate the task");
+Console.WriteLine("Press any key to stop the task");
Console.ReadKey();
await timerTask.StopTaskAsync();
\ No newline at end of file
diff --git a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerBehaviorTests.cs b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerBehaviorTests.cs
new file mode 100644
index 0000000000..1ba04d7b63
--- /dev/null
+++ b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerBehaviorTests.cs
@@ -0,0 +1,61 @@
+using Microsoft.Extensions.Time.Testing;
+
+namespace PeriodicTimerCSharpTests;
+
+[TestClass]
+public class PeriodicTimerBehaviorTests
+{
+ [TestMethod]
+ public async Task GivenMissedTicks_WhenWeWaitAgain_ThenTheyCollapseIntoOne()
+ {
+ var time = new FakeTimeProvider();
+ using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1), time);
+
+ time.Advance(TimeSpan.FromSeconds(3.5));
+
+ Assert.IsTrue(await timer.WaitForNextTickAsync());
+
+ var nextTick = timer.WaitForNextTickAsync();
+ Assert.IsFalse(nextTick.IsCompleted);
+
+ time.Advance(TimeSpan.FromSeconds(0.5));
+ Assert.IsTrue(await nextTick);
+ }
+
+ [TestMethod]
+ public void GivenAWaitInFlight_WhenWeWaitTwice_ThenTheSecondCallThrows()
+ {
+ using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
+
+ _ = timer.WaitForNextTickAsync();
+
+ Assert.ThrowsExactly(() => timer.WaitForNextTickAsync());
+ }
+
+ [TestMethod]
+ public async Task GivenAWaitInFlight_WhenWeDisposeTheTimer_ThenTheWaitReturnsFalse()
+ {
+ var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
+ var tick = timer.WaitForNextTickAsync();
+
+ timer.Dispose();
+
+ Assert.IsFalse(await tick);
+ }
+
+ [TestMethod]
+ public void GivenANewPeriod_WhenTimePasses_ThenTheTimerTicksOnTheNewSchedule()
+ {
+ var time = new FakeTimeProvider();
+ using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1), time);
+
+ timer.Period = TimeSpan.FromSeconds(5);
+ var tick = timer.WaitForNextTickAsync();
+
+ time.Advance(TimeSpan.FromSeconds(4));
+ Assert.IsFalse(tick.IsCompleted);
+
+ time.Advance(TimeSpan.FromSeconds(1));
+ Assert.IsTrue(tick.IsCompleted);
+ }
+}
diff --git a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerCSharpTests.csproj b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerCSharpTests.csproj
index d6c9824ded..ff1b110f69 100644
--- a/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerCSharpTests.csproj
+++ b/threads-csharp/PeriodicTimerCSharp/PeriodicTimerCSharpTests/PeriodicTimerCSharpTests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
enable
@@ -10,10 +10,11 @@
-
-
-
-
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive