Skip to content

Harden RendererSynchronizationContext restoration - #69356

Open
javiercn wants to merge 1 commit into
mainfrom
javiercn/investigate-renderer-sync-context
Open

javiercn wants to merge 1 commit into
mainfrom
javiercn/investigate-renderer-sync-context

Conversation

@javiercn

Copy link
Copy Markdown
Member

Why

Fixes #69323.

When queued renderer work is submitted without a flowed ExecutionContext, its continuation can inline onto the thread that releases the renderer queue. PostAsync then installs the renderer synchronization context on that caller-owned thread without an execution-context or thread-pool boundary to restore it. Subsequent CheckAccess calls can incorrectly succeed and bypass dispatcher serialization.

The triggering topology is outside normal Blazor guidance, but restoring the caller's synchronization context is inexpensive defensive hardening.

What changed

  • Complete the renderer queue marker while RendererSynchronizationContext is still current, preventing queued continuations from inlining onto the caller's thread.
  • Restore the caller's original synchronization context in an inner finally block.
  • Add a deterministic unit regression for queued work submitted with execution-context flow suppressed.
  • Add server component E2E coverage proving the component callback executes and does not overlap an occupied dispatcher.
  • No public API changes.

How to verify

  • . .\activate.ps1; dotnet test src\Components\Components\test\Microsoft.AspNetCore.Components.Tests.csproj --no-restore --filter "FullyQualifiedName~RendererSynchronizationContextTest" -v:q -p:UseIisNativeAssets=false
    • 29 passed
  • . .\activate.ps1; dotnet test src\Components\test\E2ETest\Microsoft.AspNetCore.Components.E2ETests.csproj --no-restore --filter "FullyQualifiedName~ServerComponentRenderingTest.RestoresContextWhenQueuedWorkDoesNotFlowExecutionContext" -v:q -p:UseIisNativeAssets=false -p:EnforceE2ETestPrerequisites=true
    • 1 passed
  • The new unit regression failed against the unmodified implementation.
  • An interactive InteractiveServer component repro reported Context leaked: False and Dispatcher overlapped: False twice with the change.

Risks / follow-ups

Completing the queue marker while the renderer context is current can add an asynchronous scheduling hop where a continuation previously inlined. This aligns the affected async/Send path with the synchronous dispatcher overloads, which already complete their builders before restoring the context.

No follow-up is currently required.

Copilot AI lite review requested due to automatic review settings September 16, 2026 17:57
@javiercn
javiercn requested a review from a team as a code owner September 16, 2026 17:57
@github-actions github-actions Bot added the area-blazor Includes: Blazor, Razor Components label Sep 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No unresolved issues were identified, and unit and E2E coverage validate the fix.

Pull request overview

Hardens RendererSynchronizationContext restoration to prevent context leakage and dispatcher bypass when execution-context flow is suppressed.

Changes:

  • Reorders queue-marker completion and context restoration.
  • Adds deterministic unit regression coverage.
  • Adds server component E2E coverage.
File summaries
File Description
src/Components/test/testassets/BasicTestApp/DispatchingComponent.razor Adds the suppressed-flow regression scenario.
src/Components/test/E2ETest/ServerExecutionTests/ServerComponentRenderingTest.cs Verifies context restoration and dispatcher serialization.
src/Components/Components/test/Rendering/RendererSynchronizationContextTest.cs Adds focused unit regression coverage.
src/Components/Components/src/Rendering/RendererSynchronizationContext.cs Safely orders queue completion and context restoration.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor: RendererSynchronizationContext can be left installed on an unrelated thread-pool thread, breaking Dispatcher mutual exclusion

2 participants