Skip to content

Commit 1aac9ab

Browse files
committed
Fix the Debounce component (#2759)
1 parent d2f25e5 commit 1aac9ab

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

src/Core/Utilities/InternalDebounce/DispatcherTimerExtensions.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,19 @@ public static TaskCompletionSource Debounce(this System.Timers.Timer timer, Func
3535
// If we're not in immediate mode, then we'll execute when the current timer expires.
3636
timer.Elapsed += Timer_Elapsed;
3737

38-
// Store/Update function
39-
TimerDebounceItem updateValueFactory(System.Timers.Timer k, TimerDebounceItem v)
40-
{
41-
v.Status.SetCanceled();
42-
v.Status = new TaskCompletionSource();
43-
return v.UpdateAction(action);
44-
}
45-
4638
var item = _debounceInstances.AddOrUpdate(
4739
key: timer,
4840
addValue: new TimerDebounceItem()
4941
{
5042
Status = new TaskCompletionSource(),
5143
Action = action,
5244
},
53-
updateValueFactory: updateValueFactory);
45+
updateValueFactory: (k, v) =>
46+
{
47+
v.Status.SetCanceled();
48+
v.Status = new TaskCompletionSource();
49+
return v.UpdateAction(action);
50+
});
5451

5552
// Start the timer to keep track of the last call here.
5653
timer.Start();
@@ -73,8 +70,27 @@ private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs
7370

7471
if (_debounceInstances.TryRemove(timer, out var item))
7572
{
76-
_ = (item?.Action.Invoke());
77-
item?.Status.SetResult();
73+
if (item == null)
74+
{
75+
return;
76+
}
77+
78+
var task = item.Action.Invoke();
79+
task.ContinueWith(t =>
80+
{
81+
if (t.IsFaulted)
82+
{
83+
item.Status.SetException(t.Exception);
84+
}
85+
else if (t.IsCanceled)
86+
{
87+
item.Status.SetCanceled();
88+
}
89+
else
90+
{
91+
item.Status.SetResult();
92+
}
93+
});
7894
}
7995
}
8096
}

tests/Core/Utilities/DebounceTests.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,35 @@ public async Task Debounce_Busy()
197197
[Fact]
198198
public async Task Debounce_Exception()
199199
{
200-
// Act
201-
Debounce.Run(50, async () =>
200+
await Assert.ThrowsAsync<AggregateException>(async () =>
202201
{
203-
await Task.CompletedTask;
204-
throw new InvalidProgramException("Error"); // Simulate an exception
202+
// Act
203+
Debounce.Run(50, async () =>
204+
{
205+
await Task.CompletedTask;
206+
throw new InvalidProgramException("Error"); // Simulate an exception
207+
});
208+
209+
// Wait for the debounce to complete
210+
await Debounce.CurrentTask;
205211
});
206212

207-
// Wait for the debounce to complete
208-
await Debounce.CurrentTask;
213+
// Assert
214+
Assert.False(Debounce.Busy);
215+
}
216+
217+
[Fact]
218+
public async Task Debounce_AsyncException()
219+
{
220+
await Assert.ThrowsAsync<AggregateException>(async () =>
221+
{
222+
// Act
223+
await Debounce.RunAsync(50, async () =>
224+
{
225+
await Task.CompletedTask;
226+
throw new InvalidProgramException("Error"); // Simulate an exception
227+
});
228+
});
209229

210230
// Assert
211231
Assert.False(Debounce.Busy);

0 commit comments

Comments
 (0)