SelectorQueue 1.0.0

dotnet add package SelectorQueue --version 1.0.0
                    
NuGet\Install-Package SelectorQueue -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SelectorQueue" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SelectorQueue" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SelectorQueue" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SelectorQueue --version 1.0.0
                    
#r "nuget: SelectorQueue, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SelectorQueue@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SelectorQueue&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SelectorQueue&version=1.0.0
                    
Install as a Cake Tool

SelectorQueue

<p align="center"> <img src="https://raw.githubusercontent.com/jchristn/selectorqueue/main/assets/icon.png" alt="SelectorQueue icon" width="256" height="256" /> </p>

SelectorQueue is a thread-safe, stable ordered queue for .NET. It accepts items in nondeterministic arrival order and dequeues them in a frozen sort order defined up front through a builder.

What Changed

Version 1.0.0 ships with:

  • a binary heap instead of sorted-list insertion/removal
  • immutable ordering configuration built before queue use
  • stable ordering via an internal sequence tiebreaker
  • a reduced public API focused on core queue behavior

Usage

using SelectorQueue;

public sealed class CallRecording
{
    public string Key { get; init; } = string.Empty;
    public long Size { get; init; }
    public DateTime Timestamp { get; init; }
}

SelectorQueue<CallRecording> queue = SelectorQueue
    .OrderBy<CallRecording, DateTime>(x => x.Timestamp)
    .ThenByDescending<long>(x => x.Size)
    .ThenBy<string>(x => x.Key)
    .Build();

queue.Enqueue(new CallRecording { Key = "call_003.wav", Size = 50_000, Timestamp = DateTime.Parse("2025-06-15T14:00:00Z") });
queue.Enqueue(new CallRecording { Key = "call_001.wav", Size = 30_000, Timestamp = DateTime.Parse("2025-06-15T12:00:00Z") });
queue.Enqueue(new CallRecording { Key = "call_002.wav", Size = 40_000, Timestamp = DateTime.Parse("2025-06-15T13:00:00Z") });

while (queue.TryDequeue(out CallRecording recording))
{
    Console.WriteLine($"{recording.Key} {recording.Timestamp:o} {recording.Size}");
}

If you do not need explicit ordering, use SelectorQueue.Create<T>() for a FIFO queue.

IDisposable Example

using SelectorQueue;

public sealed class WorkItem : IDisposable
{
    public WorkItem(string name, int priority)
    {
        Name = name;
        Priority = priority;
    }

    public string Name { get; }

    public int Priority { get; }

    public void Dispose()
    {
        Console.WriteLine("Disposed " + Name);
    }
}

using SelectorQueue<WorkItem> queue = SelectorQueue
    .OrderBy<WorkItem, int>(x => x.Priority)
    .Build();

queue.Enqueue(new WorkItem("low", 10));
queue.Enqueue(new WorkItem("high", 1));

WorkItem next = queue.Dequeue();
try
{
    Console.WriteLine("Processing " + next.Name);
}
finally
{
    next.Dispose();
}

// Any remaining queued WorkItem instances are disposed automatically
// when the queue is cleared or disposed.

Supported API

Ordering is configured on SelectorQueueBuilder<T> and frozen when Build() is called.

  • OrderBy
  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • Build

Queue operations are exposed on SelectorQueue<T>.

  • Enqueue
  • Dequeue
  • TryDequeue
  • Peek
  • TryPeek
  • Count
  • Clear
  • Dispose

Contract

  • Enqueue is O(log n).
  • Dequeue is O(log n).
  • Peek is O(1).
  • Equal ordering keys preserve enqueue order.
  • The queue owns items while they remain enqueued.
  • Clear() removes queued items but keeps the queue's ordering configuration for its lifetime.
  • Clear() disposes queued values that implement IDisposable.
  • Dispose() disposes queued values that implement IDisposable and permanently closes the queue.
  • After Dispose(), all queue operations throw ObjectDisposedException.
  • Dequeue() and successful TryDequeue() transfer ownership of the returned item back to the caller.
  • Empty Dequeue() and Peek() throw InvalidOperationException.
  • Empty TryDequeue() and TryPeek() return false and set the out value to default.
  • Selector delegates run before insertion. If a selector throws during Enqueue, the queue is unchanged.
  • Null keys follow Comparer<TKey>.Default semantics. For reference and nullable types, null sorts before non-null in ascending order.

Thread Safety

All queue operations are linearizable and safe for concurrent producers and consumers. Heap mutation occurs inside a single lock.

Framework

The package targets net8.0 and net10.0.

Version History

See CHANGELOG.md.

Attribution

Icon attribution: https://www.flaticon.com/free-icon/sort_306422

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 459 3/18/2026

Initial release