Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

VS hangs: project options reactor reads the caret through UI-thread COM while the UI thread waits for the reactor

オープン
#20,522 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
fsharp
領域
devtools

調査の方向性

Common/Extensions.fs と LanguageService/FSharpProjectOptionsManager.fs から開始し、FSharpProjectOptionsReactor.textViewAndCaret を getProjectOptionsFromScript まで追跡します。ScriptClosure.resolveDependencyManagerSources が caret をどのように使用するか、および非スクリプトの .fs ファイルが IVsTextViewEvents をどのように購読するかを確認してください。reactor が UI thread を決して待機せず、非スクリプトのファイルが caret データを要求しなければ完了です。

索引モデルが issue の本文から書いたものです。

説明

Needs-Triage

Visual Studio can hang for good when the project options reactor computes options for a document in F# Miscellaneous Files or for a script while the UI thread synchronously waits for those options. The reactor asks the UI thread for the caret, and the UI thread is blocked waiting for the reactor.

The caret lookup came with #18393, which gave GetProjectOptionsFromScript a caret so that a #r "nuget: …" line is not resolved while it is still being typed (#18231).

Repro steps

Caught once in the debugger, not reproduced on demand. The window is any synchronous UI-thread wait on project options for such a document while the reactor is busy with it. Here it was:

  1. A solution restored with an F# document tab whose project is not loaded, so the file opened in F# Miscellaneous Files, with breakpoints set in it.
  2. An extension's QueryStatus asked the not-yet-loaded frame for its text view, which forced EnsureDocumentFrameLoaded.
  3. Showing the frame made the debugger validate the breakpoint locations on the UI thread.

Actual behavior

Project options reactor thread:

Microsoft.VisualStudio.Services.VsTask.InternalGetResult
Microsoft.VisualStudio.Shell.ServiceProvider.QueryService
Microsoft.VisualStudio.Shell.ServiceProvider.GetService
Extensions.Document.TryGetIVsTextView              Common/Extensions.fs
Extensions.Document.TryGetTextViewAndCaretPos      Common/Extensions.fs
FSharpProjectOptionsReactor.textViewAndCaret       LanguageService/FSharpProjectOptionsManager.fs
FSharpProjectOptionsReactor.getProjectOptionsFromScript
  … tryComputeOptionsBySingleScriptOrFile, started from the reactor's MailboxProcessor loop

UI thread:

Microsoft.VisualStudio.Threading.JoinableTaskFactory.WaitSynchronouslyCore
Microsoft.VisualStudio.Threading.JoinableTask.CompleteOnCurrentThread
AbstractLanguageService<FSharpPackage, FSharpLanguageService>.VsLanguageDebugInfo.ValidateBreakpointLocation
Microsoft.VisualStudio.Platform.WindowManagement.Rdt.NotifyOnBeforeShow
WindowFrame.NotifyFrameShowing / ShowInternal / Show / TryReplacePlaceholderView
WindowFrame.LoadDocumentFrameInternalAsync
WindowFrame.EnsureDocumentFrameLoaded / GetProperty
  … an extension's IOleCommandTarget.QueryStatus asking for the active text view

ValidateBreakpointLocation goes through F# breakpoint resolution to the parse results and so to the reactor, which sits on the first stack. ServiceProvider.GlobalProvider.GetService called off the UI thread needs the UI thread, and so do the RDT, IVsTextManager.GetActiveView, IVsTextView.GetCaretPos and the IVsTextViewEvents connection point that follow it. The reactor is a MailboxProcessor, so its work is not joined to the JoinableTask the UI thread waits for, and JTF.Run never runs the request. Switching the reactor to the UI thread with SwitchToMainThreadAsync would hang the same way.

The document here was a plain .fs file, for which the caret is useless: ScriptClosure.resolveDependencyManagerSources is its only reader, and only scripts have #r "nuget: …" lines. The same path also subscribed to IVsTextViewEvents for every such .fs file and recomputed script options on every caret line change.

Expected behavior

The reactor never waits for the UI thread: the UI thread publishes the caret, the reactor reads it, and files that are not scripts do not look for it at all.

Related information

  • Windows 11, Visual Studio 18 Insiders, experimental instance
  • The code path is unchanged on main
主要言語
F#
スター
4.3k
フォーク
877
平均マージ
6日 11時間
マージ済み PR(30日)
150

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

dotnet/fsharp のほかの issue

dotnet/fsharp の issue をすべて見る

似ている issue

DevTools の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。