GPS.SimpleThreading by Payton Byrd

<PackageReference Include="GPS.SimpleThreading" Version="4.0.0" />

 ThreadBlock<TData, TResult>

public sealed class ThreadBlock<TData, TResult>
public ConcurrentDictionary<Option<TData>, ValueTuple<Option<TData>, Exception>?> Exceptions { get; }

public int MaxDegreeOfParallelism { get; set; }

public ConcurrentDictionary<Option<TData>, ValueTuple<Option<TData>, Option<TResult>>?> Results { get; }

public ThreadBlock(Func<TData, TResult> action, Action<ICollection<ValueTuple<TData, TResult>?>> continuation = null)

public ThreadBlock(Func<TData, Task<TResult>> asyncAction, Func<ICollection<ValueTuple<TData, TResult>?>, Task> asyncContinuation = null)

public void Add(TData item)

public void AddRange(IEnumerable<TData> collection)

public void AddRange(IProducerConsumerCollection<TData> collection)

public void Execute(int maxDegreeOfParallelism = -1, Action<TData> warmupItem = null, Action<Task, ValueTuple<TData, TResult>?> threadContinuation = null, CancellationToken token = default)

public Task<IEnumerable<Option<TResult>>> ExecuteAsync(int maxDegreeOfParallelism = -1, Func<TData, Task> warmupItem = null, Func<Task, ValueTuple<TData, TResult>?, Task> threadContinuation = null, CancellationToken token = default)

public void LockList()

public void OrderedAddRange(IEnumerable<TData> collection)

public void OrderedAddRange(IProducerConsumerCollection<TData> collection)

public bool Remove(TData item)