@@ -705,8 +705,13 @@ private static XDocument CreateMethodCallSnippet(string methodName, bool include
705705 private void OnModelUpdated ( object sender , ModelUpdatedEventsArgs e )
706706 {
707707 _threadingContext . ThrowIfNotOnUIThread ( ) ;
708+ _threadingContext . JoinableTaskFactory . Run ( ( ) => OnModelUpdatedAsync ( e . NewModel , CancellationToken . None ) ) ;
709+ }
708710
709- if ( e . NewModel is null )
711+ private async Task OnModelUpdatedAsync (
712+ Model ? newModel , CancellationToken cancellationToken )
713+ {
714+ if ( newModel is null )
710715 {
711716 // Signature Help was dismissed, but it's possible for a user to bring it back with Ctrl+Shift+Space.
712717 // Leave the snippet session (if any) in its current state to allow it to process either a subsequent
@@ -721,7 +726,7 @@ private void OnModelUpdated(object sender, ModelUpdatedEventsArgs e)
721726 return ;
722727 }
723728
724- if ( ! e . NewModel . UserSelected && _state . _method is not null )
729+ if ( ! newModel . UserSelected && _state . _method is not null )
725730 {
726731 // This was an implicit signature change which was not triggered by user pressing up/down, and we are
727732 // already showing an initialized argument completion snippet session, so avoid switching sessions.
@@ -739,13 +744,17 @@ private void OnModelUpdated(object sender, ModelUpdatedEventsArgs e)
739744 // TODO: The following blocks the UI thread without cancellation, but it only occurs when an argument value
740745 // completion session is active, which is behind an experimental feature flag.
741746 // https://github.com/dotnet/roslyn/issues/50634
742- var compilation = _threadingContext . JoinableTaskFactory . Run ( ( ) => document . Project . GetRequiredCompilationAsync ( CancellationToken . None ) ) ;
743- var newSymbolKey = ( e . NewModel . SelectedItem as AbstractSignatureHelpProvider . SymbolKeySignatureHelpItem ) ? . SymbolKey ?? default ;
744- var newSymbol = newSymbolKey . Resolve ( compilation , cancellationToken : CancellationToken . None ) . GetAnySymbol ( ) ;
747+ var compilation = await document . Project . GetRequiredCompilationAsync ( cancellationToken ) . ConfigureAwait ( true ) ;
748+ var newSymbolKey = ( newModel . SelectedItem as AbstractSignatureHelpProvider . SymbolKeySignatureHelpItem ) ? . SymbolKey ?? default ;
749+ var newSymbol = newSymbolKey . Resolve ( compilation , cancellationToken : cancellationToken ) . GetAnySymbol ( ) ;
745750 if ( newSymbol is not IMethodSymbol method )
746751 return ;
747752
748- MoveToSpecificMethod ( method , CancellationToken . None ) ;
753+ await MoveToSpecificMethodAsync (
754+ document , method , cancellationToken ) . ConfigureAwait ( true ) ;
755+
756+ // Don't let the compilation drop as MoveToSpecificMethodAsync wants to get the semantic model for the document.
757+ GC . KeepAlive ( compilation ) ;
749758 }
750759
751760 private static async Task < ImmutableArray < ISymbol > > GetReferencedSymbolsToLeftOfCaretAsync (
@@ -771,10 +780,12 @@ private static async Task<ImmutableArray<ISymbol>> GetReferencedSymbolsToLeftOfC
771780 /// </summary>
772781 /// <param name="method">The currently-selected method in Signature Help.</param>
773782 /// <param name="cancellationToken">A cancellation token the operation may observe.</param>
774- public void MoveToSpecificMethod ( IMethodSymbol method , CancellationToken cancellationToken )
783+ public async Task MoveToSpecificMethodAsync (
784+ Document document ,
785+ IMethodSymbol method ,
786+ CancellationToken cancellationToken )
775787 {
776- _threadingContext . ThrowIfNotOnUIThread ( ) ;
777-
788+ await _threadingContext . JoinableTaskFactory . SwitchToMainThreadAsync ( cancellationToken ) ;
778789 if ( ExpansionSession is null )
779790 {
780791 return ;
@@ -804,14 +815,6 @@ public void MoveToSpecificMethod(IMethodSymbol method, CancellationToken cancell
804815 return ;
805816 }
806817
807- var document = SubjectBuffer . CurrentSnapshot . GetOpenDocumentInCurrentContextWithChanges ( ) ;
808- if ( document is null )
809- {
810- // Couldn't identify the current document
811- ExpansionSession . EndCurrentExpansion ( fLeaveCaret : 1 ) ;
812- return ;
813- }
814-
815818 var textViewModel = TextView . TextViewModel ;
816819 if ( textViewModel == null )
817820 {
@@ -893,7 +896,7 @@ public void MoveToSpecificMethod(IMethodSymbol method, CancellationToken cancell
893896 }
894897
895898 // Now compute the new arguments for the new call
896- var semanticModel = document . GetRequiredSemanticModelAsync ( cancellationToken ) . AsTask ( ) . WaitAndGetResult ( cancellationToken ) ;
899+ var semanticModel = await document . GetRequiredSemanticModelAsync ( cancellationToken ) . ConfigureAwait ( true ) ;
897900 var position = SubjectBuffer . CurrentSnapshot . GetPosition ( adjustedTextSpan . iStartLine , adjustedTextSpan . iStartIndex ) ;
898901
899902 foreach ( var parameter in method . Parameters )
@@ -903,7 +906,7 @@ public void MoveToSpecificMethod(IMethodSymbol method, CancellationToken cancell
903906 foreach ( var provider in GetArgumentProviders ( document . Project . Solution . Workspace ) )
904907 {
905908 var context = new ArgumentContext ( provider , semanticModel , position , parameter , value , cancellationToken ) ;
906- _threadingContext . JoinableTaskFactory . Run ( ( ) => provider . ProvideArgumentAsync ( context ) ) ;
909+ await provider . ProvideArgumentAsync ( context ) . ConfigureAwait ( true ) ;
907910
908911 if ( context . DefaultValue is not null )
909912 {
0 commit comments