Skip to content

feat: report and reuse a sequencer's owning thread - #227

Merged
glennawatson merged 2 commits into
mainfrom
feat/thread-affine-sequencer
Sep 28, 2026
Merged

glennawatson merged 2 commits into
mainfrom
feat/thread-affine-sequencer

Conversation

@glennawatson

@glennawatson glennawatson commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Sequencers that run work on a UI thread can now say whether the calling thread owns them, and hand back one shared sequencer per UI owner.

  • IThreadAffineSequencer.CheckAccess() in ReactiveUI.Primitives.Core reports whether the calling thread owns a sequencer. The Avalonia, WPF, WinForms, MAUI, WinUI, Android and Apple sequencers implement it in both flavours.
  • For(owner) on AvaloniaScheduler, DispatcherSequencer, ControlSequencer, MauiDispatcherSequencer, DispatcherQueueSequencer and HandlerSequencer returns one cached sequencer per dispatcher, control, dispatcher queue or looper, and returns the shared instance for its own owner.
  • WitnessOnOwner(sequencer) and a new WitnessOnSignal<T> constructor deliver a notification inline when the caller owns the sequencer and nothing is waiting; anything raised later queues behind what is already waiting.
  • Updates PublicApiSharp.Analyzers to 2.1.0, TUnit to 1.70.1 and Microsoft.Maui.Core to 10.0.110 for the net10 heads.

Why

ReactiveUI.Binding routes every view write onto the thread that owns the view. Each platform currently does that through its own dispatcher code, because no sequencer can say which thread owns it. With CheckAccess and For, the binding platform packages route through these sequencers instead, starting with a new Avalonia package for reactiveui/ReactiveUI.Avalonia#216.

Breaking changes

None. Every change adds API; existing constructors, Main, Current and Instance behave as before.

How this was verified

Tests cover the new operator path and the Avalonia and MAUI sequencers' CheckAccess and For. The WPF, WinForms, WinUI, Android and Apple sequencer changes compile here but their tests only run on Windows or a device, so CI is their first run. The Apple PublicAPI baselines were edited by hand because Apple heads do not build on Linux.

Notes for the reviewer

Start with WitnessOnSignal{T}.cs: the inline path only runs when an owner is passed, so the existing constructor is unchanged. The For lookups hold sequencers in a ConditionalWeakTable keyed by the owner. Blazor and Wasm do not implement IThreadAffineSequencer: the Blazor sequencer has no dispatcher to ask, and Wasm has no owning thread. Some PublicAPI baselines were re-sorted by the regeneration tool without API changes.

Checklist

  • I have read the Contribute guide
  • The PR title follows Conventional Commits
  • Tests cover this change, or the summary says why they do not
  • New or changed public API has XML documentation

Add IThreadAffineSequencer to ReactiveUI.Primitives.Core. Its CheckAccess
reports whether the calling thread owns a sequencer. The Avalonia, WPF,
WinForms, MAUI, WinUI, Android and Apple sequencers implement it in both
flavours.

Each owner-backed sequencer gains a static For(owner) that returns one
sequencer per dispatcher, control, dispatcher queue or looper. It returns
the shared instance for that instance's own owner.

WitnessOnSignal gains an owner-aware constructor and a WitnessOnOwner
extension. They deliver inline when the calling thread owns the sequencer
and nothing is waiting, and queue otherwise, so a notification never
overtakes one that is already waiting.
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.78%. Comparing base (f68fe17) to head (155d187).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #227   +/-   ##
=======================================
  Coverage   99.78%   99.78%           
=======================================
  Files         785      785           
  Lines       24850    24923   +73     
  Branches     2946     2957   +11     
=======================================
+ Hits        24796    24869   +73     
  Misses         54       54           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@glennawatson
glennawatson merged commit 4cdcacc into main Sep 28, 2026
15 checks passed
@glennawatson
glennawatson deleted the feat/thread-affine-sequencer branch September 28, 2026 06:20
@github-actions

Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Oct 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

⌂ 换网址