@@ -159,7 +159,7 @@ module private FSharpQuickInfo =
159159
160160type internal FSharpAsyncQuickInfoSource
161161(
162- serviceProvider : IServiceProvider ,
162+ statusBar : StatusBar ,
163163 xmlMemberIndexService: IVsXMLMemberIndexService,
164164 checkerProvider: FSharpCheckerProvider,
165165 projectInfoManager: FSharpProjectOptionsManager,
@@ -186,6 +186,9 @@ type internal FSharpAsyncQuickInfoSource
186186
187187interface IAsyncQuickInfoSourcewith
188188override __.Dispose () = () // no cleanup necessary
189+
190+ // This method can be called from the background thread.
191+ // Do not call IServiceProvider.GetService here.
189192override __.GetQuickInfoItemAsync ( session : IAsyncQuickInfoSession , cancellationToken : CancellationToken ) : Task < QuickInfoItem > =
190193let triggerPoint = session.GetTriggerPoint( textBuffer.CurrentSnapshot)
191194match triggerPoint.HasValuewith
@@ -211,7 +214,7 @@ type internal FSharpAsyncQuickInfoSource
211214let mainDescription , documentation , typeParameterMap , usage , exceptions = ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray()
212215 XmlDocumentation.BuildDataTipText( documentationBuilder, mainDescription.Add, documentation.Add, typeParameterMap.Add, usage.Add, exceptions.Add, quickInfo.StructuredText)
213216let imageId = Tokenizer.GetImageIdForSymbol( quickInfo.Symbol, quickInfo.SymbolKind)
214- let navigation = QuickInfoNavigation( serviceProvider , checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
217+ let navigation = QuickInfoNavigation( statusBar , checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
215218let docs = joinWithLineBreaks[ documentation; typeParameterMap; usage; exceptions]
216219let content = QuickInfoViewProvider.provideContent( imageId, mainDescription, docs, navigation)
217220let span = getTrackingSpan quickInfo.Span
@@ -242,7 +245,7 @@ type internal FSharpAsyncQuickInfoSource
242245] |> ResizeArray
243246let docs = joinWithLineBreaks[ documentation; typeParameterMap; usage; exceptions]
244247let imageId = Tokenizer.GetImageIdForSymbol( targetQuickInfo.Symbol, targetQuickInfo.SymbolKind)
245- let navigation = QuickInfoNavigation( serviceProvider , checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
248+ let navigation = QuickInfoNavigation( statusBar , checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
246249let content = QuickInfoViewProvider.provideContent( imageId, mainDescription, docs, navigation)
247250let span = getTrackingSpan targetQuickInfo.Span
248251return QuickInfoItem( span, content)
@@ -260,6 +263,11 @@ type internal FSharpAsyncQuickInfoSourceProvider
260263 checkerProvider: FSharpCheckerProvider,
261264 projectInfoManager: FSharpProjectOptionsManager
262265) =
266+
263267interface IAsyncQuickInfoSourceProviderwith
264268override __.TryCreateQuickInfoSource ( textBuffer : ITextBuffer ) : IAsyncQuickInfoSource =
265- new FSharpAsyncQuickInfoSource( serviceProvider, serviceProvider.XMLMemberIndexService, checkerProvider, projectInfoManager, textBuffer) :> IAsyncQuickInfoSource
269+ // GetService calls must be made on the UI thread
270+ // It is safe to do it here (see #4713)
271+ let statusBar = StatusBar( serviceProvider.GetService< SVsStatusbar, IVsStatusbar>())
272+ let xmlMemberIndexService = serviceProvider.XMLMemberIndexService
273+ new FSharpAsyncQuickInfoSource( statusBar, xmlMemberIndexService, checkerProvider, projectInfoManager, textBuffer) :> IAsyncQuickInfoSource