< Summary

Information
Class: Amusoft.Toolkit.Threading.Debouncer
Assembly: Amusoft.Toolkit.Threading
File(s): /home/runner/work/Amusoft.Toolkit.Threading/Amusoft.Toolkit.Threading/src/Amusoft.Toolkit.Threading/Debouncer.cs
Tag: 19_10540409038
Line coverage
100%
Covered lines: 20
Uncovered lines: 0
Coverable lines: 20
Total lines: 48
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
FromStackAsync()100%44100%

File(s)

/home/runner/work/Amusoft.Toolkit.Threading/Amusoft.Toolkit.Threading/src/Amusoft.Toolkit.Threading/Debouncer.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.Runtime.CompilerServices;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using Amusoft.Toolkit.Threading.Compat;
 7using Amusoft.Toolkit.Threading.Exceptions;
 8
 9namespace Amusoft.Toolkit.Threading;
 10
 11/// <summary>
 12/// Debouncing API
 13/// </summary>
 14public class Debouncer
 15{
 116  private static readonly ConcurrentDictionary<LoaderIdentity, DebounceStack> Stacks = new(new IdentityComparer());
 17
 118  private static readonly ConditionalWeakTable<DebounceStack, LoaderIdentity> IdOfStack = new();
 19
 20  /// <summary>
 21  /// ensures that the last call with a given identity will provide the result for all awaiting tasks
 22  /// </summary>
 23  /// <typeparam name="T"></typeparam>
 24  /// <returns></returns>
 25  public static async Task<T> FromStackAsync<T>(Func<CancellationToken, Task<T>> expression, LoaderIdentity identity)
 26  {
 627    var current = Stacks.GetOrAdd(identity,
 628      loaderIdentity =>
 629      {
 330        var newStack = new DebounceStack<T>();
 331        newStack.Task.ContinueWith(_ =>
 332          {
 333            if (Stacks.TryRemove(loaderIdentity, out var prevStack))
 334              IdOfStack.Remove(prevStack);
 335          }
 336        );
 337        IdOfStack.Add(newStack, loaderIdentity);
 338        return newStack;
 639      });
 40
 641    if (current is not DebounceStack<T> stack)
 142      throw new TypeMismatchException(current.GetType(), typeof(DebounceStack<T>), identity);
 43
 544    stack.CancelAndUpdate(expression);
 45
 546    return await stack.Task;
 547  }
 48}

Methods/Properties

.cctor()
FromStackAsync()