66using GitHub . Models ;
77using GitHub . Services ;
88using GitHub . Logging ;
9+ using GitHub . Helpers ;
910using GitHub . TeamFoundation . Services ;
1011using Serilog ;
1112using Microsoft . VisualStudio . TeamFoundation . Git . Extensibility ;
@@ -46,45 +47,72 @@ public VSGitExt(IGitHubServiceProvider serviceProvider, IVSUIContextFactory fact
4647 // Start with empty array until we have a chance to initialize.
4748 ActiveRepositories = Array . Empty < ILocalRepositoryModel > ( ) ;
4849
49- if ( context . IsActive && TryInitialize ( ) )
50+ PendingTasks = InitializeAsync ( ) ;
51+ }
52+
53+ async Task InitializeAsync ( )
54+ {
55+ try
5056 {
51- // Refresh ActiveRepositories on background thread so we don't delay startup.
52- QueueRefreshActiveRepositories ( ) ;
57+ if ( ! context . IsActive || ! await TryInitialize ( ) )
58+ {
59+ // If we're not in the UIContext or TryInitialize fails, have another go when the UIContext changes.
60+ context . UIContextChanged += ContextChanged ;
61+ log . Debug ( "VSGitExt will be initialized later" ) ;
62+ }
5363 }
54- else
64+ catch ( Exception e )
5565 {
56- // If we're not in the UIContext or TryInitialize fails, have another go when the UIContext changes.
57- context . UIContextChanged += ContextChanged ;
58- log . Debug ( "VSGitExt will be initialized later" ) ;
66+ log . Error ( e , "Initializing" ) ;
5967 }
6068 }
6169
6270 void ContextChanged ( object sender , VSUIContextChangedEventArgs e )
6371 {
64- // If we're in the UIContext and TryInitialize succeeds, we can stop listening for events.
65- // NOTE: this event can fire with UIContext=true in a TFS solution (not just Git).
66- if ( e . Activated && TryInitialize ( ) )
72+ if ( e . Activated )
6773 {
68- // Refresh ActiveRepositories on background thread so we don't delay UI context change.
69- QueueRefreshActiveRepositories ( ) ;
70- context . UIContextChanged -= ContextChanged ;
71- log . Debug ( "Initialized VSGitExt on UIContextChanged" ) ;
74+ PendingTasks = ContextChangedAsync ( ) ;
7275 }
7376 }
7477
75- bool TryInitialize ( )
78+ async Task ContextChangedAsync ( )
7679 {
80+ try
81+ {
82+ // If we're in the UIContext and TryInitialize succeeds, we can stop listening for events.
83+ // NOTE: this event can fire with UIContext=true in a TFS solution (not just Git).
84+ if ( await TryInitialize ( ) )
85+ {
86+ context . UIContextChanged -= ContextChanged ;
87+ log . Debug ( "Initialized VSGitExt on UIContextChanged" ) ;
88+ }
89+ }
90+ catch ( Exception e )
91+ {
92+ log . Error ( e , "UIContextChanged" ) ;
93+ }
94+ }
95+
96+ async Task < bool > TryInitialize ( )
97+ {
98+ // GetService must be called on the Main thread.
99+ await ThreadingHelper . SwitchToMainThreadAsync ( ) ;
100+
77101 gitService = serviceProvider . GetService < IGitExt > ( ) ;
78102 if ( gitService != null )
79103 {
80104 gitService . PropertyChanged += ( s , e ) =>
81105 {
82106 if ( e . PropertyName == nameof ( gitService . ActiveRepositories ) )
83107 {
84- QueueRefreshActiveRepositories ( ) ;
108+ // Execute tasks in sequence using thread pool (TaskScheduler.Default).
109+ PendingTasks = PendingTasks . ContinueWith ( _ => RefreshActiveRepositories ( ) , TaskScheduler . Default ) ;
85110 }
86111 } ;
87112
113+ // Do this after we start listening so we don't miss an event.
114+ await Task . Run ( ( ) => RefreshActiveRepositories ( ) ) ;
115+
88116 log . Debug ( "Found IGitExt service and initialized VSGitExt" ) ;
89117 return true ;
90118 }
@@ -93,12 +121,6 @@ bool TryInitialize()
93121 return false ;
94122 }
95123
96- void QueueRefreshActiveRepositories ( )
97- {
98- // Execute tasks in sequence using thread pool (TaskScheduler.Default).
99- PendingTasks = PendingTasks . ContinueWith ( _ => RefreshActiveRepositories ( ) , TaskScheduler . Default ) ;
100- }
101-
102124 void RefreshActiveRepositories ( )
103125 {
104126 try
@@ -140,6 +162,6 @@ private set
140162 /// <summary>
141163 /// Tasks that are pending execution on the thread pool.
142164 /// </summary>
143- public Task PendingTasks { get ; private set ; } = Task . CompletedTask ;
165+ public Task PendingTasks { get ; private set ; }
144166 }
145167}
0 commit comments