@@ -177,8 +177,13 @@ public int ResolveName(string? pszName, uint dwFlags, out IVsEnumDebugName? ppNa
177177 return VSConstants . S_FALSE ;
178178 }
179179
180+ // NOTE(cyrusn): We have to wait here because the debuggers' ResolveName
181+ // call is synchronous. In the future it would be nice to make it async.
180182 ppNames = this . ThreadingContext . JoinableTaskFactory . Run ( async ( ) =>
181183 {
184+ // We're in a blocking JTF run. So ConfigureAwait(true) all calls to ensure we're coming back
185+ // and using the blocked thread whenever possible.
186+
182187 using ( Logger . LogBlock ( FunctionId . Debugging_VsLanguageDebugInfo_ResolveName , CancellationToken . None ) )
183188 {
184189 using var waitContext = _uiThreadOperationExecutor . BeginExecute (
@@ -192,14 +197,11 @@ public int ResolveName(string? pszName, uint dwFlags, out IVsEnumDebugName? ppNa
192197 {
193198 var solution = _languageService . Workspace . CurrentSolution ;
194199
195- // NOTE(cyrusn): We have to wait here because the debuggers' ResolveName
196- // call is synchronous. In the future it would be nice to make it async.
197200 if ( _breakpointService != null )
198201 {
199202 var breakpoints = await _breakpointService . ResolveBreakpointsAsync (
200- solution , pszName , cancellationToken ) . ConfigureAwait ( false ) ;
201- var debugNames = await breakpoints . SelectAsArrayAsync (
202- bp => CreateDebugNameAsync ( bp , cancellationToken ) ) . ConfigureAwait ( true ) ;
203+ solution , pszName , cancellationToken ) . ConfigureAwait ( true ) ;
204+ var debugNames = breakpoints . SelectAsArray ( bp => CreateDebugName ( bp , cancellationToken ) ) ;
203205
204206 return new VsEnumDebugName ( debugNames ) ;
205207 }
@@ -210,23 +212,28 @@ public int ResolveName(string? pszName, uint dwFlags, out IVsEnumDebugName? ppNa
210212 } ) ;
211213
212214 return ppNames != null ? VSConstants . S_OK : VSConstants . E_NOTIMPL ;
213- }
214215
215- private async ValueTask < IVsDebugName > CreateDebugNameAsync (
216- BreakpointResolutionResult breakpoint , CancellationToken cancellationToken )
217- {
218- var document = breakpoint . Document ;
219- var filePath = _languageService . Workspace . GetFilePath ( document . Id ) ;
220- var text = await document . GetValueTextAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
221- var span = text . GetVsTextSpanForSpan ( breakpoint . TextSpan ) ;
222- // If we're inside an Venus code nugget, we need to map the span to the surface buffer.
223- // Otherwise, we'll just use the original span.
224- var mappedSpan = await span . MapSpanFromSecondaryBufferToPrimaryBufferAsync (
225- this . ThreadingContext , document . Id , cancellationToken ) . ConfigureAwait ( true ) ;
226- if ( mappedSpan != null )
227- span = mappedSpan . Value ;
228-
229- return new VsDebugName ( breakpoint . LocationNameOpt , filePath ! , span ) ;
216+ IVsDebugName CreateDebugName (
217+ BreakpointResolutionResult breakpoint , CancellationToken cancellationToken )
218+ {
219+ // We're in a blocking jtf run. So CA(true) all calls to ensure we're coming bac
220+ // and using the blocked thread whenever possible.
221+
222+ var document = breakpoint . Document ;
223+ var filePath = _languageService . Workspace . GetFilePath ( document . Id ) ;
224+
225+ // We're (unfortunately) blocking the UI thread here. So avoid async io as we actually
226+ // awant the IO to complete as quickly as possible, on this thread if necessary.
227+ var text = document . GetTextSynchronously ( cancellationToken ) ;
228+ var span = text . GetVsTextSpanForSpan ( breakpoint . TextSpan ) ;
229+ // If we're inside an Venus code nugget, we need to map the span to the surface buffer.
230+ // Otherwise, we'll just use the original span.
231+ var mappedSpan = span . MapSpanFromSecondaryBufferToPrimaryBuffer ( this . ThreadingContext , document . Id ) ;
232+ if ( mappedSpan != null )
233+ span = mappedSpan . Value ;
234+
235+ return new VsDebugName ( breakpoint . LocationNameOpt , filePath ! , span ) ;
236+ }
230237 }
231238
232239 public int ValidateBreakpointLocation ( IVsTextBuffer pBuffer , int iLine , int iCol , VsTextSpan [ ] pCodeSpan )
0 commit comments