[Review agent] Calibrate Blazor DI scope teardown IJSObjectReference disposal findings (#69970, #70340)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Documentación
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- csharp, javascript
- Área
- backend, documentation
Línea de trabajo
Start with docs/BlazorComponentsGuidance.md and .github/agents/review-candidate-verifier.agent.md, then check the cited Storage.cs, CookieStore.cs, Window.cs, and Screen.cs conventions and the JSObjectReference.DisposeAsync behavior. Document the scope teardown behavior for Interactive Server and WebAssembly, and update verifier guidance to check sibling patterns, exception handling, and whether disposal is reachable outside teardown. Done when the guidance covers both findings and the cited review cases.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
Across two Microsoft.AspNetCore.Components.Platform PRs (#69970 and #70340), review passes produced P2 lifecycle findings around IJSObjectReference disposal during Blazor DI scope teardown (IInternalAsyncDisposal.InternalDisposeAsync) without establishing a reachable production trigger or accounting for existing repository conventions:
-
Non-waiting pending acquisition at DI scope disposal (
#69970Screen.cs:103and#70340Window.cs:88):- In
Screen.cs(#69970) andWindow.cs(#70340),GetReferenceAsync()caches_jsRuntime.GetValueAsync<IJSObjectReference>(...).AsTask(), andInternalDisposeAsync()intentionally only disposes_referenceTask.Resultwhen_referenceTask is { IsCompletedSuccessfully: true }with the comment:// Don't wait for a pending acquisition. It could hold up scope disposal until the JS interop timeout. if (_referenceTask is { IsCompletedSuccessfully: true } referenceTask) { await referenceTask.Result.DisposeAsync().ConfigureAwait(false); } - Review arms (
gpt-5.6-solandgpt-6.1-solon #69970;gpt-6.1-solon #70340) flagged aP2leak if the scope is disposed whileGetReferenceAsync()is still in flight and the JS reference arrives afterward. - While the source-level mechanism is conditionally possible if an
IJSRuntimecompletesGetValueAsyncafterInternalDisposeAsyncchecks_referenceTask.IsCompletedSuccessfully(andJSCallbackFactory.ImportModuleAsyncin #70340 explicitly disposes a late-arriving module to satisfyBrowserJSRuntimeunit tests that callServiceProvider.DisposeAsync()while holding"import"), this exact non-waiting pattern is already established inStorage.cs:111-115andCookieStore.cs:179-183onmain. - Furthermore,
Window.AddEventListenerAsyncalready throwsObjectDisposedExceptionafterawait GetReferenceAsync()(Window.cs:70), and as the author explained in #69970 comment4489650667, Blazor DI scope disposal in supported hosts runs during Interactive Server circuit teardown (where inbound interop completion and disposal are serialized on the circuit/renderer dispatcher) or WebAssembly page unload — so aP2production leak claim is not established without a concrete supported-host trigger.
- In
-
Exception propagation during
IJSObjectReference.DisposeAsyncat DI scope disposal (#70340Window.cs:159, CCR comment4489112121):- Separately from the pending-acquisition pattern above, CCR comment
4489112121(and corroborating review notes) claimed thatawait referenceTask.Result.DisposeAsync()inWindow.InternalDisposeAsync()could throwJSDisconnectedExceptionorTaskCanceledExceptionduring circuit teardown and skip subsequent feature cleanup. - As the author noted in #70340 comment
4489969683,CircuitHost.DisposeAsynccallsJSRuntime.MarkPermanentlyDisconnected()before disposing the DI scope (preventing new outbound calls from being sent), andJSObjectReference.DisposeAsyncalready suppressesJSDisconnectedException(since #64773).
- Separately from the pending-acquisition pattern above, CCR comment
Describe the solution you'd like
- Calibrate Blazor Components / JSInterop review guidance (
docs/BlazorComponentsGuidance.mdand/or.github/agents/review-candidate-verifier.agent.md):- Document the Blazor DI scope teardown contract for scoped JS interop projections (
Window,Screen,Storage,CookieStore):- In Interactive Server,
CircuitHostmarksJSRuntimepermanently disconnected before scope disposal runs, inbound completions are coordinated through the circuit/renderer dispatcher, andJSObjectReference.DisposeAsyncalready ignoresJSDisconnectedException. - In WebAssembly, the DI scope for browser platform services lives until page unload.
- Non-waiting disposal of a lazy
Task<IJSObjectReference>(if (_referenceTask is { IsCompletedSuccessfully: true })) that matches existingStorage/CookieStoreconventions is intentional so scope disposal cannot hang on a pending JS interop call, and should not be elevated as aP2blocking production leak unless a reachable non-teardown disposal path is established in the PR.
- In Interactive Server,
- Document the Blazor DI scope teardown contract for scoped JS interop projections (
- Require
review-candidate-verifierto check existing sibling conventions andJSObjectReference.DisposeAsyncexception contracts:- Before keeping a
P2disposal-leak orJSDisconnectedExceptionpropagation candidate on anIJSObjectReference, verify whetherJSObjectReference.DisposeAsyncalready suppresses the claimed exception and whether the disposal path is reachable in a supported host outside circuit/page teardown.
- Before keeping a
Additional context
- Tracked under #70231.
- Evidence PRs:
- #69970 (
src/Components/Platform/src/Screen.cs:103, author explanation in4489650667) - #70340 (
src/Components/Platform/src/Window.cs:88andWindow.cs:159, author explanation in4489969683)
- #69970 (
- Lenguaje dominante
- C#
- Estrellas
- 38.5k
- Forks
- 11.6k
- Merge medio
- 3 d 1 h
- PR fusionados (30 d)
- 289
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de dotnet/aspnetcore
-
area-networking
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/aspnetcore#70545 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
area-infrastructure
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
dotnet/aspnetcore#70524 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[OpenTelemetry] Hosting replaces an Activity.DisplayName that the app set, when a route matchesAbiertoarea-hosting Regression
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/aspnetcore#70516 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
[SSE] ServerSentEventsResult.WrapEvents is missing [EnumeratorCancellation], so RequestAborted never reaches the app's generator on the IAsyncEnumerable<T> overloadPosiblemente ocupada @bharatprajapati-coder la tomó hace 1 día. Abiertoarea-minimal
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/aspnetcore#70419 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
[Blazor] DefaultInMemoryCircuitPersistenceProvider never disposes the retention CancellationTokenSource when a persist is rejected at capacityPosiblemente ocupada @Vinoth2562000 la tomó hace 2 días. Abiertoarea-blazor
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
dotnet/aspnetcore#70418 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de dotnet/aspnetcore
Issues similares
-
bug emitter:client:csharp
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
microsoft/typespec#12572 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
needs-area-label
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
AWS Lambda: KeyNotFoundException drops HTTP-triggered transactions when allowAllHeaders is disabledAbiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
newrelic/newrelic-dotnet-agent#3949 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 87/100
Los mantenedores suelen responder en 1 día
-
low-priority performance
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
dekobon/big-code-analysis#1879 · 1 comentario ·
Los mantenedores suelen responder en 1 día