Skip to content

Commit 1cf015d

Browse files
author
Rick van Dam
authored
Fix multi dispose scheduler and timer (net-daemon#799)
* Check if already disposed and skip if so * Add unit test to check dispose functionality
1 parent c12c0c9 commit 1cf015d

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

src/Extensions/NetDaemon.Extensions.Scheduling.Tests/Scheduling/DisposableSchedulerTest.cs

+9
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ public void SchedulePeriodicStopsAfterDisposeOfSubscriber()
7878
inner.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
7979
called.Should().Be(3);
8080
}
81+
82+
[Fact]
83+
public void DisposeTwice_NoException()
84+
{
85+
var (_, disposableScheduler) = CreateScheduler();
86+
87+
disposableScheduler.Dispose();
88+
disposableScheduler.Dispose();
89+
}
8190

8291
private (TestScheduler inner, DisposableScheduler disposableScheduler) CreateScheduler()
8392
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Threading;
2+
using NetDaemon.Extensions.Scheduler;
3+
using Xunit;
4+
5+
namespace NetDaemon.Extensions.Scheduling.Tests;
6+
7+
public class DisposableTimerTest
8+
{
9+
[Fact]
10+
public void DisposeTwice_NoException()
11+
{
12+
var timer = new DisposableTimer(CancellationToken.None);
13+
14+
timer.Dispose();
15+
timer.Dispose();
16+
}
17+
}

src/Extensions/NetDaemon.Extensions.Scheduling/DisposableScheduler.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@ public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<I
7676
/// <inheritdoc />
7777
public void Dispose()
7878
{
79-
_isDisposed = true;
80-
81-
_cancellationTokenSource.Cancel();
82-
_cancellationTokenSource.Dispose();
79+
if (!_isDisposed)
80+
{
81+
_cancellationTokenSource.Cancel();
82+
_cancellationTokenSource.Dispose();
83+
_isDisposed = true;
84+
}
8385
}
8486
}

src/Extensions/NetDaemon.Extensions.Scheduling/DisposableTimer.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public sealed class DisposableTimer : IDisposable
1010
{
1111
private readonly CancellationTokenSource _combinedToken;
1212
private readonly CancellationTokenSource _internalToken;
13+
private bool _disposed;
14+
1315
/// <summary>
1416
/// Constructor
1517
/// </summary>
@@ -29,8 +31,11 @@ public DisposableTimer(CancellationToken token)
2931
/// </summary>
3032
public void Dispose()
3133
{
32-
_internalToken.Cancel();
33-
_combinedToken.Dispose();
34-
_internalToken.Dispose();
34+
if (!_disposed){
35+
_internalToken.Cancel();
36+
_combinedToken.Dispose();
37+
_internalToken.Dispose();
38+
_disposed = true;
39+
}
3540
}
3641
}

0 commit comments

Comments
 (0)