Fix WebWorker hang when debugging Blazor WASM apps in Visual Studio#125617
Merged
Conversation
Contributor
|
Tagging subscribers to this area: @steveisok, @thaystg, @dotnet/dotnet-diag |
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a Visual Studio debugging hang for Blazor WebAssembly apps that use Web Workers by ensuring worker targets are resumed correctly when Chrome/VS pause them during attach/startup, preventing the worker from getting stuck before executing its module import.
Changes:
- On
Target.attachedToTargetforworker, sendRuntime.runIfWaitingForDebuggerafter creating the worker execution context. - In
OnDebuggerPaused(default case), whenJustMyCodeis enabled and a worker session isn’t runtime-ready yet, resume the worker instead of forwarding the pause to the IDE.
You can also share your feedback on Copilot code review. Take the survey.
The cobaltSveMicro job added in dotnet/performance#5127 targets linux_arm64 on perfcobalt, which generates a dependency on the build_linux_arm64_release_coreclr job. This job was never created because linux_arm64 was not enabled in perf-build-jobs.yml, causing all dotnet-runtime-perf pipeline builds to fail with a YAML validation error since March 18. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Mar 18, 2026
thaystg
approved these changes
Mar 19, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
When debugging a Blazor WebAssembly app that uses Web Workers (via the
dotnet new webworkertemplate, see dotnet/aspnetcore#65037) in Visual Studio, the worker thread hangs indefinitely during startup. The app never completes initialization and the worker appears stuck at importing worker's module.This PR fixes two issues in the BrowserDebugProxy (
MonoProxy) that together cause the hang.You can use this app to see the problem: BlazorAppRepro.zip
Root Cause
Issue 1 — Worker never resumed after Chrome pauses it on attach:
When VS sends
Target.setAutoAttach({ waitForDebuggerOnStart: true }), Chrome pauses all new worker threads until the debugger explicitly sendsRuntime.runIfWaitingForDebugger. The proxy'sTarget.attachedToTargethandler for workers only calledCreateWorkerExecutionContext()but never sentRuntime.runIfWaitingForDebugger, leaving the worker frozen before any JS executed.Issue 2 —
Debugger.pausedevent forwarded to IDE instead of being resumed:Even after resuming the worker, VS's JavaScript debugger auto-attaches with
breakOnLoad: true, which fires aDebugger.pausedevent on the worker session. InOnDebuggerPaused's default case, whenJustMyCodeis enabled and the execution context isn't runtime-ready (IsRuntimeReady == false), the handler returnsfalse— forwarding the pause to VS. VS's JS debugger receives the pause but doesn't resume it, leaving the worker stuck. Shortly after, the CDP connection crashes withObjectDisposedException.Changes
MonoProxy.cs— two targeted fixes:Target.attachedToTargethandler: For worker targets, sendRuntime.runIfWaitingForDebuggerafter creating the worker execution context. This tells Chrome to unpause the worker thread.OnDebuggerPauseddefault case: When the session belongs to a worker (detected viacontext.ParentContext != null) and the runtime isn't ready yet, callSendResumeinstead of returningfalse. This prevents the pause from being forwarded to the IDE and lets the worker continue booting its WASM runtime.Testing
Manually verified with a Blazor WASM Standalone app + webworker library project in VS 2022 (by replacing the .dlls VS uses):
Home.razor) hit correctlyKnown Limitation
Breakpoints in C# code running inside the Web Worker (e.g.,
[JSExport]methods in the worker library) do not get hit. The debug proxy currently only attaches its SDB agent to the main page's WASM runtime, not the worker's second runtime. This is a pre-existing architectural limitation and is out of scope for this PR but I would like to have it solved as well. Any ideas on how to do it are welcome.Contributes to dotnet/aspnetcore#65823.