@@ -38,55 +38,73 @@ private class RazorStartupService(
3838 AbstractRazorCohostLifecycleService ? razorCohostLifecycleService ) : ILspService , IOnInitialized , IDisposable
3939 {
4040 private readonly CancellationTokenSource _disposalTokenSource = new ( ) ;
41- private IDisposable ? _activation ;
41+ private IDisposable ? _cohostActivation ;
42+ private IDisposable ? _razorFilePresentActivation ;
4243
4344 public void Dispose ( )
4445 {
4546 razorCohostLifecycleService ? . Dispose ( ) ;
4647
47- _activation ? . Dispose ( ) ;
48- _activation = null ;
48+ _razorFilePresentActivation ? . Dispose ( ) ;
49+ _razorFilePresentActivation = null ;
50+ _cohostActivation ? . Dispose ( ) ;
51+ _cohostActivation = null ;
4952 _disposalTokenSource . Cancel ( ) ;
5053 }
5154
52- public async Task OnInitializedAsync ( ClientCapabilities clientCapabilities , RequestContext context , CancellationToken cancellationToken )
55+ public Task OnInitializedAsync ( ClientCapabilities clientCapabilities , RequestContext context , CancellationToken cancellationToken )
5356 {
5457 if ( context . ServerKind is not ( WellKnownLspServerKinds . AlwaysActiveVSLspServer or WellKnownLspServerKinds . CSharpVisualBasicLspServer ) )
5558 {
5659 // We have to register this class for Any server, but only want to run in the C# server in VS or VS Code
57- return ;
60+ return Task . CompletedTask ;
5861 }
5962
6063 if ( cohostStartupService is null && razorCohostLifecycleService is null )
6164 {
62- return ;
63- }
64-
65- if ( razorCohostLifecycleService is not null )
66- {
67- // If we have a cohost lifecycle service, fire pre-initialization, which happens when the LSP server starts up, but before
68- // the UIContext is activated.
69- await razorCohostLifecycleService . LspServerIntializedAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
65+ return Task . CompletedTask ;
7066 }
7167
7268 if ( uIContextActivationService is null )
7369 {
74- // Outside of VS, we want to initialize immediately.. I think?
70+ PreinitializeRazor ( ) ;
7571 InitializeRazor ( ) ;
7672 }
7773 else
7874 {
79- _activation = uIContextActivationService . ExecuteWhenActivated ( Constants . RazorCohostingUIContext , InitializeRazor ) ;
75+ // There are two initialization methods for Razor, which looks odd here, but are really controlled by UI contexts.
76+ // This method fires for any Roslyn project, but not all Roslyn projects are Razor projects, so the first UI context
77+ // triggers where there is a project with a Razor capability present in the solution, and the next is when a Razor file
78+ // is opened in the editor. ie these two lines look the same, but really they do different levels of initialization.
79+ _razorFilePresentActivation = uIContextActivationService . ExecuteWhenActivated ( Constants . RazorCapabilityPresentUIContext , PreinitializeRazor ) ;
80+ _cohostActivation = uIContextActivationService . ExecuteWhenActivated ( Constants . RazorCohostingUIContext , InitializeRazor ) ;
8081 }
8182
82- return ;
83+ return Task . CompletedTask ;
84+
85+ void PreinitializeRazor ( )
86+ {
87+ this . PreinitializeRazorAsync ( _disposalTokenSource . Token ) . ReportNonFatalErrorAsync ( ) ;
88+ }
8389
8490 void InitializeRazor ( )
8591 {
8692 this . InitializeRazorAsync ( clientCapabilities , context , _disposalTokenSource . Token ) . ReportNonFatalErrorAsync ( ) ;
8793 }
8894 }
8995
96+ private async Task PreinitializeRazorAsync ( CancellationToken cancellationToken )
97+ {
98+ if ( cancellationToken . IsCancellationRequested ) return ;
99+
100+ await TaskScheduler . Default . SwitchTo ( alwaysYield : true ) ;
101+
102+ if ( razorCohostLifecycleService is not null )
103+ {
104+ await razorCohostLifecycleService . LspServerIntializedAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
105+ }
106+ }
107+
90108 private async Task InitializeRazorAsync ( ClientCapabilities clientCapabilities , RequestContext context , CancellationToken cancellationToken )
91109 {
92110 // The LSP server will dispose us when the server exits, but VS could decide to activate us later.
0 commit comments