Open
Conversation
Introduce a new Async module for ReactiveUI.Extensions: adds comprehensive async support including AsyncContext, observables, observers, connectable observables, a wide set of operators, subjects, internals (gates, cancelable subscriptions, anonymous types), and async disposables (Composite, Serial, SingleAssignment, helpers). Also update Directory.Packages.props (bump Microsoft.SourceLink.GitHub and add several System/Microsoft packages) and adjust the ReactiveUI.Extensions project file to include the new sources. This commit scaffolds full asynchronous reactive primitives and utilities used across the extension library.
Introduce a full Async Observable implementation and comprehensive test suite. Adds core async types and bridge code (IObservableAsync, IObserverAsync, ObservableAsync, ObserverAsync, ObservableBridgeExtensions, AsyncContext), many operator implementations (Merge, Concat, CombineLatest, Zip, SelectMany, Delay, Retry, Throttle, Timeout, StartWith, TakeWhile, SkipWhile, etc.), subject variants and internals (multicast, wrapped observers, cancelable subscriptions), and subject mixins. Also adds numerous NUnit test files under src/ReactiveUI.Extensions.Tests/Async (AdditionalOperatorTests, BridgeTests, CombiningOperatorTests, CoverageBoostTests, DeepCoverageTests, DisposableTests, ErrorHandlingOperatorTests, FactoryObservableTests, FilteringOperatorTests, ResultAndInfrastructureTests, SubjectTests, TerminalOperatorTests, TimeBasedOperatorTests, TransformationOperatorTests, AsyncTestHelpers) and updates project/test wiring. These changes enable bridging with System.Reactive, expand operator coverage, and improve test coverage across many edge cases.
Clean up and refactor various async operator and subject implementations: remove unused usings and redundant comments, replace explicit local types with var for consistency, simplify a method to an expression-bodied form, and use IsEmpty for buffer checks. Add XML documentation for ConcatEnumerableObservable and ZipObservable to clarify behavior and type parameters. These changes improve readability, reduce compiler/editor warnings, and clarify intent without altering behavior.
Add a comprehensive "Async Observables (IObservableAsync<T>)" section to the README covering design goals, quick start, API catalog, core interfaces/types, factory methods, operators (transformation, filtering, combining, timing, aggregation, error handling), subjects, bridging/conversion, async disposables, examples and usage notes. Also update Performance Notes and Thread Safety with async-specific guidance, add a changelog line announcing the async-native framework, fix a small typography change (allocation‑aware hyphen), and correct a few code snippet var/formatting issues.
Introduce a new DebounceUntil<T>(..., TimeSpan, Func<T,bool>, IScheduler) overload that uses the supplied scheduler for Delay, enabling deterministic scheduling in tests. Update the DebounceUntil unit test to use TestScheduler, pass it into the operator, replace Thread.Sleep with scheduler.AdvanceBy, and adjust timing to use FromTicks so the test runs deterministically.
In StartAsync, add a sentinel Interlocked.Increment(ref _active) before subscribing to sources and replace the Volatile.Read check with Interlocked.Decrement(ref _active) after the loop. This prevents a synchronously-completing inner source from driving _active to zero before subsequent sources are subscribed, avoiding premature termination of the merge. Also adds explanatory comments and uses interlocked operations for correct race-free behavior.
Add new test file src/ReactiveUI.Extensions.Tests/Async/CombineLatestOperatorTests.cs containing comprehensive NUnit tests for the CombineLatest async operator. Covers arities 2–8 and verifies behavior for emissions (no emission until all sources have values, latest-value combinings), error propagation and completion semantics, error-resume forwarding, disposal handling (including double-dispose and ignoring resumes after dispose), and several cross-cutting edge cases.
Restructure and expand .editorconfig with detailed code-style, analyzer and naming rules. Add CI/config files (codecov.yml, global.json, testconfig.json) and replace the old .sln with a .slnx. Remove a parallel AssemblyInfo and apply widespread updates to the Async implementation and corresponding tests (subjects, operators, disposables, internals, and test project files) to align with the new style and analyzer expectations.
Add AsyncTestHelpers.WaitForConditionAsync to provide polling-based waits with timeouts, and replace Thread.Sleep/manual polling in tests with this helper. Updated TimeBasedOperatorTests and ReactiveExtensionsTests to await conditions (and assert the wait succeeded) for more reliable, deterministic timing in async tests, and added the necessary using directive in ReactiveExtensionsTests.
Increase timeouts and make async test waits more robust to reduce flakiness. Updated TimeBasedOperatorTests and ReactiveExtensionsTests to use a 5s WaitForConditionAsync instead of shorter delays, replaced a Task.Delay with WaitForConditionAsync that checks both result and exception, and strengthened a retry test to wait for the expected error count before asserting.
Extend flaky test waits and make completion assertions more robust. Increased TimeBasedOperatorTests wait timeouts from 2s to 5s to reduce timing-related failures. In ReactiveExtensionsTests replaced a simple Task.WaitAsync with WaitForConditionAsync that verifies both completion flag and result count, and added an assertion for the condition result. These changes aim to stabilize CI/test runs by allowing more time and using a deterministic completion check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Update / Feature
What is the new behavior?
Introduce a new Async module for ReactiveUI.Extensions: adds comprehensive async support including AsyncContext, observables, observers, connectable observables, a wide set of operators, subjects, internals (gates, cancellable subscriptions, anonymous types), and async disposables (Composite, Serial, SingleAssignment, helpers).
Also update Directory.Packages.props (bump Microsoft.SourceLink.GitHub and add several System/Microsoft packages) and adjust the ReactiveUI.Extensions project file to include the new sources.
This commit scaffolds full asynchronous reactive primitives and utilities used across the extension library.
Introduce a full Async Observable implementation and comprehensive test suite.
Adds core async types and bridge code (IObservableAsync, IObserverAsync, ObservableAsync, ObserverAsync, ObservableBridgeExtensions, AsyncContext), many operator implementations (Merge, Concat, CombineLatest, Zip, SelectMany, Delay, Retry, Throttle, Timeout, StartWith, TakeWhile, SkipWhile, etc.), subject variants and internals (multicast, wrapped observers, cancellable subscriptions), and subject mixins.
Also adds numerous NUnit test files under src/ReactiveUI.Extensions.Tests/Async (AdditionalOperatorTests, BridgeTests, CombiningOperatorTests, CoverageBoostTests, DeepCoverageTests, DisposableTests, ErrorHandlingOperatorTests, FactoryObservableTests, FilteringOperatorTests, ResultAndInfrastructureTests, SubjectTests, TerminalOperatorTests, TimeBasedOperatorTests, TransformationOperatorTests, AsyncTestHelpers) and updates project/test wiring.
These changes enable bridging with System.Reactive, expand operator coverage, and improve test coverage across many edge cases.
Clean up and refactor various async operator and subject implementations: remove unused usings and redundant comments, replace explicit local types with var for consistency, simplify a method to an expression-bodied form, and use IsEmpty for buffer checks.
Add XML documentation for ConcatEnumerableObservable and ZipObservable to clarify behavior and type parameters. These changes improve readability, reduce compiler/editor warnings, and clarify intent without altering behavior.
Add a comprehensive "Async Observables (IObservableAsync)" section to the README covering design goals, quick start, API catalogue, core interfaces/types, factory methods, operators (transformation, filtering, combining, timing, aggregation, error handling), subjects, bridging/conversion, async disposables, examples and usage notes.
Also update Performance Notes and Thread Safety with async-specific guidance, add a changelog line announcing the async-native framework, fix a small typography change (allocation‑aware hyphen), and correct a few code snippet var/formatting issues.
What might this PR break?
Minor changes to existing code.
Added support for ValueTask, IObservableAsync, IObserverAsync and IAsyncDisposable
Please check if the PR fulfills these requirements
Other information: