Read a script's caret without waiting for the UI thread - #20523
Open
xperiandri wants to merge 3 commits into
Open
Read a script's caret without waiting for the UI thread#20523xperiandri wants to merge 3 commits into
xperiandri wants to merge 3 commits into
Conversation
Contributor
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
|
Contributor
|
🔍 Tooling Safety Check — Affects-Design-Time, Affects-Restore
|
The project options reactor looked up the caret itself through ServiceProvider.GlobalProvider, the RDT, IVsTextView and an IVsTextViewEvents connection point, all of which need the UI thread. When the UI thread synchronously waited on project options (breakpoint validation when a document frame is shown), the reactor waited for the UI thread and the UI thread for the reactor. An IWpfTextViewCreationListener now publishes the caret of the focused editor into the text buffer's properties, and the reactor only reads it. Only scripts look for it: FCS uses the caret only to skip the `#r "nuget: ..."` line being typed. Fixes dotnet#20522 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xperiandri
force-pushed
the
fix/script-caret-deadlock
branch
from
September 11, 2026 14:44
89eaf2a to
550abf6
Compare
T-Gro
self-requested a review
September 11, 2026 15:12
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.
Description
Fixes #20522
The project options reactor looked up the caret of a script or F# Miscellaneous Files document itself:
ServiceProvider.GlobalProvider, the RDT,IVsTextManager.GetActiveView,IVsTextView.GetCaretPos, and anIVsTextViewEventsconnection point. That code came with #18393. All of it needs the UI thread, so when the UI thread synchronously waits on project options, as breakpoint validation does when a document frame is shown, the reactor waits for the UI thread and the UI thread waits for the reactor. The reactor is aMailboxProcessor, so its work is not joined to the UI thread'sJoinableTask, and moving the lookup to the UI thread withSwitchToMainThreadAsyncwould hang the same way.Now the UI thread publishes the caret and the reactor only reads it:
FocusedCaretTracker, anIWpfTextViewCreationListenerfor F# editors, keeps aFocusedCaretin each text buffer's properties. It holds the caret of whichever editor on the buffer has focus (ValueNonewhile none has), and raisesLineChangedwhen the caret moves to another line or focus enters or leaves the buffer's editors. These are the same moments thatOnChangeCaretLine,OnKillFocusandOnSetFocusreported before.FocusedCaretthrough the document'sSourceTextcontainer, which does not need the UI thread. It passes the caret toGetProjectOptionsFromScriptand re-submits the script options onLineChanged, as it did on the text view events before.ScriptClosure.resolveDependencyManagerSources, to skip the#r "nuget: …"line being typed, and only scripts have those lines. A plain.fsfile in F# Miscellaneous Files (the file that hung in VS hangs: project options reactor reads the caret through UI-thread COM while the UI thread waits for the reactor #20522) no longer subscribes to caret moves, and no longer recomputes script options on every caret line change.TryGetIVsTextView,TryGetTextViewAndCaretPos,subscribeToTextViewEvents,TextViewEventsHandlerandConnectionPointSubscriptionhad no other callers and are removed with the opens that only they needed.One behaviour follows the description of #18393 more closely than its code did. Moving focus to another window now submits the
#r "nuget: …"line: without focus there is no caret. Before,GetActiveView(0, …)returned the last active view whether or not it had focus, so the line stayed excluded.Checklist
JoinableTaskFactory.Run; the editor tests have no UI thread and a nullGlobalProvider, which is why they never hit it.🤖 Generated with Claude Code