Skip to content
CAI
Software that uses CAICheck a score

dotnet/reactive

47.5

Weak · 5 August 2026

20.4k

lines of production code

C#

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a .NET library providing asynchronous extensions for LINQ and Reactive programming. It implements \IAsyncEnumerable\-based operators for both queryable and enumerable data streams, alongside a comprehensive Reactive Extensions (Rx) implementation featuring async observables, schedulers, and disposable management. The codebase includes tooling for API comparison and performance benchmarking, while maintaining backward compatibility through deprecation facades and extensive xUnit test coverage.

How it got here

2012–2016 — Modernization and platform expansion

11 changes.

This period focused on modernizing the build infrastructure and expanding cross-platform test coverage for the Interactive Extensions library. Key changes included removing legacy async LINQ implementations, restructuring the project with modern .NET tooling, and adding integration tests for a wide range of .NET platforms and frameworks.

2017 — Async LINQ and test modernization

26 changes.

This period focused on modernizing the codebase by migrating the test suite to xUnit and refactoring async LINQ operators to use ValueTask and cancellation tokens for improved performance. The work also involved reorganizing the code structure into individual files, adding new operators like MaxByWithTies, and introducing tooling to compare synchronous and asynchronous APIs.

2018–2026 — Async Rx and LINQ modernization

5 changes.

This period focused on introducing comprehensive async support for Reactive Extensions and enhancing LINQ performance measurement. The codebase expanded with new async types, schedulers, and disposable patterns, while simultaneously refactoring source generators and updating API approvals to reflect modernized, backward-compatible interfaces.

Features

Add AsyncRx.NET playground with sample implementations

A new playground project has been added to the AsyncRx.NET solution, providing a collection of sample implementations for various async reactive patterns. The file \Program.cs\ includes examples for operators such as Buffer (time-based and sliding), Delay, GroupBy, Concat, Merge, Range, Replay, and others, allowing users to explore and test these features interactively.

AsyncRx.NET/Playground · high confidence

Added API comparison tool to identify missing async operators

A new console application, ApiCompare, has been added to the AsyncRx.NET project. This tool compares the public static methods of the synchronous Observable class against the AsyncObservable class, identifying which synchronous operators are missing from the async API. The tool explicitly excludes certain methods (such as AsObservable, ToObservable, Subscribe, and various push-to-pull adapters) to focus on the core operator gaps. This aids developers in understanding the current state of the async API coverage.

AsyncRx.NET/ApiCompare · high confidence

Added ApiCompare tool to detect missing async overloads

A new ApiCompare tool has been added to the Ix.NET source tree. This utility automatically compares synchronous LINQ operators against their asynchronous counterparts, identifying any missing async overloads or excess methods. The tool is configured with specific exceptions and whitelists (e.g., ToHashSet, ForEachAsync) to handle known differences and first-class conversions.

Ix.NET/Source/ApiCompare · high confidence

Added Interactive Extensions demo project and deprecation facade

A new 'Playground' console application has been added to the Ix.NET source tree, providing a runnable demo that showcases LINQ and Interactive Extensions patterns for IEnumerable, IQueryable, IAsyncEnumerable, and IAsyncQueryable. The project includes a custom DemoAttribute to tag and organize demo methods, and a Program class that reflects over these methods to present an interactive menu. Additionally, a new file enables a deprecation facade in the runtime assembly, marking the old async enumerable types as obsolete to guide users toward the newer IAsyncEnumerable-based APIs.

Ix.NET/Source/Playground · medium confidence

Added integration test projects for multiple .NET platforms

Added a new \Ix.NET/Integration\ directory containing a solution file and empty placeholder projects for various target platforms, including .NET 4.5, .NET 4.6.1, .NET Core, .NET Standard 1.4, Windows 8.1, Windows 10 (UWP), Windows Phone 8, Windows Phone 8.1, iOS, and tvOS. These projects serve as the foundation for integration testing across different .NET environments.

Ix.NET/Integration · high confidence

Added performance benchmarking suite for LINQ interface designs

A new program, Program.cs, has been added to the FasterLinq source directory to provide a performance suite that compares synchronous and asynchronous interface designs. This tool allows users to benchmark the execution speed of standard LINQ operations against faster, custom enumerable implementations, helping to evaluate the performance characteristics of different data access patterns.

Ix.NET/Source/FasterLinq · high confidence

Added performance benchmarks for System.Interactive LINQ operators

A new benchmarking project has been added to measure the performance of several System.Interactive operators, including Buffer, Defer, IgnoreElements, Min, Max, and Retry. This allows developers to track and optimize the efficiency of these common LINQ operations.

Ix.NET/Source/Benchmarks.System.Interactive · high confidence

AsyncRx.NET project structure and build configuration

The AsyncRx.NET area now includes a new solution file (AsyncRx.NET.sln) that organizes the project into logical groups (lib, dev) and registers specific projects (System.Reactive.Async, Playground, ApiCompare). A new Directory.build.props file establishes global build properties, including enabling embedded PDBs, assembly signing, and setting the C\# language version to latest. Additionally, a version.json file is introduced to configure versioning via Nerdbank.GitVersioning (v3.4.231) and define release branch patterns, while the coverlet.collector dependency is updated to v3.2.0 for test coverage.

AsyncRx.NET · high confidence

Introduce async Reactive Extensions (AsyncRx) with new types and schedulers

The AsyncRx.NET/System.Reactive.Async area adds a complete set of async-friendly Reactive Extensions types, including \IAsyncObservable\<T\>\, \IAsyncObserver\<T\>\, and their base classes (\AsyncObservable\, \AsyncObserver\, \AsyncObservableBase\, \AsyncObserverBase\). It also introduces async-aware concurrency primitives such as \IAsyncScheduler\, \AsyncScheduler\, and various scheduler implementations (\ImmediateAsyncScheduler\, \TaskPoolAsyncScheduler\, \SynchronizationContextAsyncScheduler\). Additionally, the diff adds a suite of async disposable types (\AsyncDisposable\, \CancellationAsyncDisposable\, \CompositeAsyncDisposable\, \SerialAsyncDisposable\, \SingleAssignmentAsyncDisposable\, \StableCompositeAsyncDisposable\) to support asynchronous resource management.

AsyncRx.NET/System.Reactive.Async · high confidence

Introduced internal extension methods for async enumeration and task utilities

Added new internal static classes, AsyncEnumerableExt and TaskExt, within the System.Threading.Tasks namespace. AsyncEnumerableExt provides a helper to configure cancellation and context for async enumerables, while TaskExt exposes a pre-completed Task\<bool\> singleton for optimization. These additions support the broader migration of standard query operators to System.Linq.Async.

Ix.NET/Source/System.Linq.Async/System/Threading · medium confidence

Updated IntroToRx documentation for Rx v6.1

The 'Introduction to Rx' guide has been updated to align with the Rx v6.1 release. This includes documentation for the new \TakeUntil(CancellationToken)\ overload, the \DisposeWith\ extension method for \IDisposable\, and the \ResetExceptionDispatchState\ operator. The update also clarifies the rules regarding the reuse of exception objects in scenarios where Rx will rethrow them.

Rx.NET · high confidence

Removals

Removal of legacy build infrastructure and async LINQ implementation

The \Ix\ directory's legacy build infrastructure has been removed, specifically the \Common.targets\ and \Import.targets\ MSBuild configuration files that previously managed build settings for .NET 3.5, 4.0, Silverlight, and Windows Phone 7. Additionally, the \Interactive Extensions.sln\ solution file and associated Visual Studio test configuration files (\\.vsmdi\, \\.testsettings\) have been deleted. This change also removes the entire \System.Interactive.Async\ namespace, including all asynchronous LINQ extension methods (such as \Aggregate\, \Count\, \Min\, \Sum\, and \Catch\) and their supporting internal classes, effectively stripping the library of its async enumeration capabilities.

Ix · high confidence

Architecture

Restructures Ix.NET build and solution configuration

The Ix.NET source directory has been restructured to modernize the build system and improve developer experience. A new \.editorconfig\ file is introduced to suppress specific C\# naming rule violations for internal and protected fields, addressing stricter analyzer behavior in modern .NET versions. The project now uses \Directory.Build.props\ and \Directory.Build.targets\ to centralize build properties, including enabling nullable reference types and setting up source link and versioning via Nerdbank.GitVersioning. A new \AsyncQueryableGenerator.t4\ template is added to generate async queryable methods, and solution files (\Ix.NET.sln\, \Ix.Async.NET.sln\) are updated to reflect the new project structure, including a new benchmarking project and test projects. Additionally, a \CodeCoverage.runsettings\ file is added to configure code coverage collection, and a \version.json\ file is introduced to manage versioning for the 7.0.1-preview release.

Ix.NET/Source · high confidence

Behavioural changes

Added AssemblyInfo configuration for System.Linq.Async.Queryable

The System.Linq.Async.Queryable assembly now includes an AssemblyInfo.cs file that sets the neutral resources language to en-US, marks the assembly as not visible to COM, and declares CLS compliance. This establishes the standard assembly metadata and licensing headers for the library.

Ix.NET/Source/System.Linq.Async.Queryable/Properties · high confidence

Added AssemblyInfo.cs for System.Linq.Async

The System.Linq.Async assembly now includes an explicit AssemblyInfo.cs file that defines standard assembly metadata, including setting the neutral resources language to en-US, marking the assembly as non-ComVisible, and declaring CLS compliance.

Ix.NET/Source/System.Linq.Async/Properties · high confidence

Added runtime directive files to fix failing tests

Added System.Interactive.Async.rd.xml and System.Interactive.rd.xml files to configure the .NET Native linker for reflection usage, resolving test failures caused by the linker stripping required types.

Ix.NET/Source/System.Interactive.Async/Properties, Ix.NET/Source/System.Interactive/Properties · high confidence

Added runtime directives and updated assembly metadata

The System.Interactive.Async.Providers assembly now includes an .rd.xml file that configures reflection directives, enabling dynamic type resolution for the library. Additionally, the assembly metadata has been updated to reflect .NET Foundation copyright and MIT licensing, with ComVisible set to false and CLS compliance enabled.

Ix.NET/Source/System.Interactive.Async.Providers/Properties · high confidence

Added runtime directives for System.Interactive.Providers

The System.Interactive.Providers library now includes an rd.xml file that configures the .NET Native linker to preserve all types via Dynamic="Required All". This ensures that reflection-based operations on the library's types will function correctly in pre-compiled scenarios, addressing the TODO comment to optimize for types that actually need reflection.

Ix.NET/Source/System.Interactive.Providers/Properties · high confidence

AsyncQueryable API modernized with ValueTask and cancellation support

The AsyncQueryable API has been modernized to return ValueTask for better performance and ergonomics, particularly for aggregate operations. The query provider now supports cancellation tokens in the GetAsyncEnumerator method, allowing operations to be cancelled. Additionally, the API surface has been refactored to improve code generation stability and nullable context support.

Ix.NET/Source/System.Linq.Async.Queryable/System · high confidence

AsyncQueryableEx generated code updated to use ValueTask and nullable reference types

The generated \AsyncQueryableEx\ code has been regenerated to switch return types from \Task\ to \ValueTask\ for aggregate operators (such as \AverageAsync\), which improves ergonomics and performance in high-frequency scenarios. The generated files also now include \\#nullable enable\ and handle nullability for parameters like \comparer\, addressing previous nullable warnings and improving type safety for users of the \System.Interactive.Async\ library.

Ix.NET/Source/System.Interactive.Async.Providers/System · high confidence

Extracted internal and async-support interfaces into separate files

The System.Interactive library has been refactored to improve code organization and support asynchronous enumeration patterns. New interfaces including IAwaitable, IAwaiter, IBuffer, IRefCountList, and IYielder have been extracted into their own files. Additionally, internal implementation classes such as MaxRefCountList, RefCountList, and Yielder have been separated into individual files, enhancing modularity and maintainability of the LINQ query operators.

Ix.NET/Source/System.Interactive/System/Linq · high confidence

Internal refactoring of TaskExt and addition of fair merge implementation

The TaskExt class has been marked as internal, reducing its public surface area. A new internal WhenAnyValueTask implementation has been added to support a fair and cheaper concurrent Merge operation, utilizing a queue-based completion tracking system with locking to manage task completion order and avoid race conditions.

Ix.NET/Source/System.Interactive.Async · medium confidence

Major refactoring of System.Linq.Async operators to support async iterators and cancellation

The \System.Linq.Async\ library has been significantly refactored to modernize its implementation. Key changes include adopting C\# 8.0 features like async iterators and local functions, which improves performance and reduces memory allocations. The codebase now supports deep cancellation via \CancellationToken\ propagation across operators, and many operators (such as \Aggregate\, \All\, \Any\, \Average\, \Cast\, and \Append/Prepend\) have been rewritten or generated to use \ValueTask\ and \IAsyncIListProvider\ for better ergonomics and efficiency. Additionally, a centralized \Error\ class was introduced for exception handling, and obsolete methods were marked to guide users toward the new \AsyncEnumerable\ API.

Ix.NET/Source/System.Linq.Async/System/Linq/Operators · high confidence

Migration of System.Interactive.Async operators to System.Linq.AsyncEnumerable

The \System.Interactive.Async\ library has been refactored to align with the new \System.Linq.AsyncEnumerable\ API introduced in .NET 10. This change moves the implementation of standard and non-standard LINQ operators (such as \Amb\, \Buffer\, \Catch\, \Concat\, and \AverageAsync\) into the \AsyncEnumerableEx\ partial class within the \System.Interactive.Async\ package. This ensures that these operators remain available for use with \IAsyncEnumerable\<T\>\ even after the deprecated \System.Linq.Async\ package is removed, while also adopting modern C\# 8.0 features like \async\ iterators and \ValueTask\ for improved ergonomics and performance.

Ix.NET/Source/System.Interactive.Async/System · high confidence

QueryableEx restructured and enhanced with MinBy/MaxBy with ties

The QueryableEx class has been split into separate files, with the main implementation moved to a new QueryableEx.cs file and the generated/extended methods moved to QueryableEx.Generated.cs. This change introduces MinByWithTies and MaxByWithTies methods that return a list of all elements sharing the minimum or maximum key value, rather than just the first one. Additionally, the code now uses nameof() for null-argument checks, updates the license header to MIT, and includes conditional compilation for REFERENCE\_ASSEMBLY.

Ix.NET/Source/System.Interactive.Providers/System · high confidence

Refactor async LINQ operators to use ValueTask and cancellation tokens

The async LINQ operators have been refactored to use ValueTask for internal operations like predicates, selectors, and partitioning, which improves performance by avoiding unnecessary state machine allocations. Additionally, cancellation tokens are now properly propagated through the async enumeration pipeline, with new methods like WithCancellation and GetCountAsync supporting cancellation. The change also introduces IAsyncPartition and IAsyncIListProvider interfaces to enable optimized paths for array and list conversions, while removing unused cancellation tokens and fixing nullable warnings.

Ix.NET/Source/System.Linq.Async/System/Linq · high confidence

Refactored source generator into multiple files and added deprecated facade generation

The System.Linq.Async.SourceGenerator was refactored into multiple files (AsyncMethod.cs, AsyncMethodGrouping.cs, AsyncOverloadsGenerator.cs, DeprecatedDuplicateBuilder.cs, etc.) to improve maintainability. The generator now produces a 'DuplicateAsyncEnumerableAsAsyncEnumerableDeprecated' attribute and builds a facade class named 'AsyncEnumerableDeprecated' containing duplicate definitions of deprecated AsyncEnumerable methods. This ensures backward compatibility by allowing existing code using deprecated methods to continue working with deprecation warnings, while the main API moves to System.Linq.AsyncEnumerable.

Ix.NET/Source/System.Linq.Async.SourceGenerator · medium confidence

Reorganize LINQ operators into individual files and introduce new sequence operators

The System.Interactive LINQ operators have been refactored from a single large file into separate, individual files (e.g., Buffer.cs, Case.cs, Create.cs, Defer.cs, Distinct.cs, DistinctUnti1Changed.cs, Do.cs, DoWhile.cs, Expand.cs, Finally.cs, For.cs, ForEach.cs, Generate.cs, Hide.cs, If.cs, IgnoreElements.cs, IsEmpty.cs, Max.cs, MaxBy.cs, MaxByWithTies.cs, and Memoize.cs). This reorganization improves code maintainability and readability. Additionally, new operators are introduced: \MaxByWithTies\ and \MaxBy\ (marked obsolete) to return all elements with the maximum key value, and \Case\ for conditional sequence selection. The \Distinct\ and \DistinctUnti1Changed\ operators have been split into separate files for better organization. The \Memoize\ operator now supports specifying a reader count for multi-reader scenarios.

Ix.NET/Source/System.Interactive/System/Linq/Operators · high confidence

Updated API approval snapshots for System.Interactive and System.Interactive.Async

The API approval tests for System.Interactive and System.Interactive.Async have been updated to reflect the current public API surface. This includes the addition of new \AverageAsync\ overloads supporting async selectors, the deprecation of \MaxBy\/\MinBy\ in favor of \MaxByWithTies\/\MinByWithTies\, and the removal of \AsyncEnumerable\ from the public API in favor of \System.Linq.AsyncEnumerable\. The \Obsolete\ attributes on \MaxBy\ and \MinBy\ now provide specific migration guidance to users.

Ix.NET/Source/Tests.System.Interactive.ApiApprovals · high confidence

Test coverage

Add base test class for async enumerable operations; Added Rx.NET plugin compatibility tests; Added and modernized async enumerable tests; Added and reorganized tests for System.Interactive.Async LINQ operators; Added integration test projects for Ix.NET across multiple target frameworks; Added placeholder files for Rx-PlatformServices package targets; Added test infrastructure and generated tests for AsyncQueryableEx; Added test infrastructure for async operations; Added tests for AsyncQueryable operators; Added tests for async enumerable naming conventions and optimizations; Added unit tests for Linq operators; Expanded test coverage for System.Linq.Async operators; Migrate test suite to xUnit and update test assertions.

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 47 → 48 (+0.1)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.08.19) — scores are not directly comparable.

Lenses

  • Code Health 38 → 38 (+0.0)
  • Architecture 100 → 100 (+0.0)
  • Maturity 60 → 61 (+1.0)
  • Readiness 39 → 39 (+0.0)
  • Security 72 → 72 (+0.0)
  • Performance 81 → 81 (+0.0)

Resolved (3)

  • LLM evaluation failed
  • Off-boarding risk: anonymized user #1
  • redundant comment (AsyncRx.NET/Playground/Program.cs)

New (6)

  • Off-boarding risk: anonymized user #1
  • XML-doc coverage: ApiCompare (AsyncRx.NET/ApiCompare/ApiCompare.csproj)
  • XML-doc coverage: Playground (AsyncRx.NET/Playground/Playground.csproj)
  • XML-doc coverage: System.Reactive.Async(netstandard2.0) (AsyncRx.NET/System.Reactive.Async/System.Reactive.Async.csproj)
  • redundant comment (AsyncRx.NET/ApiCompare/Program.cs)
  • redundant comment (AsyncRx.NET/System.Reactive.Async/Threading/Tasks/TaskAsyncObservableExtensions.cs)

Architecture

  • Unchanged — 2 containers · 0 contexts · 0 edges

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

dotnet/reactive was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 5 August 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 94b5d5ab912789f5abe9a72138a25bbd716fe59c — the exact code this score is about.
  • Scored under rubric-2026.08.19 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer latest.