@@ -37,6 +37,8 @@ internal sealed class VisualStudioProjectFactory : IVsTypeScriptVisualStudioProj
3737 private readonly ImmutableArray < IAnalyzerAssemblyRedirector > _analyzerAssemblyRedirectors ;
3838 private readonly IVsService < SVsBackgroundSolution , IVsBackgroundSolution > _solution ;
3939
40+ private readonly JoinableTask _initializationTask ;
41+
4042 [ ImportingConstructor ]
4143 [ Obsolete ( MefConstruction . ImportingConstructorMessage , error : true ) ]
4244 public VisualStudioProjectFactory (
@@ -51,6 +53,23 @@ public VisualStudioProjectFactory(
5153 _dynamicFileInfoProviders = fileInfoProviders . AsImmutableOrEmpty ( ) ;
5254 _analyzerAssemblyRedirectors = analyzerAssemblyRedirectors . AsImmutableOrEmpty ( ) ;
5355 _solution = solution ;
56+
57+ _initializationTask = _threadingContext . JoinableTaskFactory . RunAsync (
58+ async ( ) =>
59+ {
60+ var cancellationToken = _threadingContext . DisposalToken ;
61+
62+ // HACK: Fetch this service to ensure it's still created on the UI thread; once this is
63+ // moved off we'll need to fix up it's constructor to be free-threaded.
64+
65+ // yield if on the main thread, as the VisualStudioMetadataReferenceManager construction can be fairly expensive
66+ // and we don't want the case where VisualStudioProjectFactory is constructed on the main thread to block on that.
67+ await _threadingContext . JoinableTaskFactory . SwitchToMainThreadAsync ( alwaysYield : true , cancellationToken ) ;
68+ _visualStudioWorkspaceImpl . Services . GetRequiredService < VisualStudioMetadataReferenceManager > ( ) ;
69+
70+ _visualStudioWorkspaceImpl . SubscribeExternalErrorDiagnosticUpdateSourceToSolutionBuildEvents ( ) ;
71+ _visualStudioWorkspaceImpl . SubscribeToSourceGeneratorImpactingEvents ( ) ;
72+ } ) ;
5473 }
5574
5675 public Task < ProjectSystemProject > CreateAndAddToWorkspaceAsync ( string projectSystemName , string language , CancellationToken cancellationToken )
@@ -59,6 +78,8 @@ public Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(string projectSys
5978 public async Task < ProjectSystemProject > CreateAndAddToWorkspaceAsync (
6079 string projectSystemName , string language , VisualStudioProjectCreationInfo creationInfo , CancellationToken cancellationToken )
6180 {
81+ await _initializationTask . JoinAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
82+
6283 // The rest of this method can be ran off the UI thread. We'll only switch though if the UI thread isn't already blocked -- the legacy project
6384 // system creates project synchronously, and during solution load we've seen traces where the thread pool is sufficiently saturated that this
6485 // switch can't be completed quickly. For the rest of this method, we won't use ConfigureAwait(false) since we're expecting VS threading
0 commit comments