1414
1515namespace GitHub . Services
1616{
17- [ Export ( typeof ( IUsageTracker ) ) ]
18- [ PartCreationPolicy ( CreationPolicy . Shared ) ]
1917 public class UsageTracker : IUsageTracker
2018 {
2119 const string StoreFileName = "ghfvs.usage" ;
2220 static readonly Calendar cal = CultureInfo . InvariantCulture . Calendar ;
2321
22+ readonly IUIProvider uiProvider ;
23+ readonly DispatcherTimer timer ;
24+
2425 IMetricsService client ;
25- readonly IConnectionManager connectionManager ;
26+ IConnectionManager connectionManager ;
2627 IPackageSettings userSettings ;
27- readonly IVSServices vsservices ;
28- readonly DispatcherTimer timer ;
29- readonly string storePath ;
30- readonly IServiceProvider serviceProvider ;
28+ IVSServices vsservices ;
29+ string storePath ;
30+ bool firstRun = true ;
3131
3232 Func < string , bool > fileExists ;
3333 Func < string , Encoding , string > readAllText ;
3434 Action < string , string , Encoding > writeAllText ;
3535 Action < string > dirCreate ;
3636
3737 [ ImportingConstructor ]
38- public UsageTracker (
39- IProgram program ,
40- IConnectionManager connectionManager ,
41- IVSServices vsservices ,
42- [ Import ( typeof ( SVsServiceProvider ) ) ] IServiceProvider serviceProvider )
38+ public UsageTracker ( IUIProvider uiProvider )
4339 {
44- this . serviceProvider = serviceProvider ;
40+ this . uiProvider = uiProvider ;
4541
4642 fileExists = ( path ) => System . IO . File . Exists ( path ) ;
4743 readAllText = ( path , encoding ) =>
@@ -65,17 +61,11 @@ public UsageTracker(
6561 } ;
6662 dirCreate = ( path ) => System . IO . Directory . CreateDirectory ( path ) ;
6763
68- this . connectionManager = connectionManager ;
69- this . vsservices = vsservices ;
7064 this . timer = new DispatcherTimer (
71- TimeSpan . FromMinutes ( 1 ) ,
65+ TimeSpan . FromMinutes ( 3 ) ,
7266 DispatcherPriority . Background ,
7367 TimerTick ,
7468 Dispatcher . CurrentDispatcher ) ;
75- this . storePath = System . IO . Path . Combine (
76- Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ,
77- program . ApplicationName ,
78- StoreFileName ) ;
7969
8070 RunTimer ( ) ;
8171 }
@@ -145,8 +135,29 @@ public void IncrementLoginCount()
145135 SaveUsage ( usage ) ;
146136 }
147137
138+ void Initialize ( )
139+ {
140+ // The services needed by the usage tracker are loaded when they are first needed to
141+ // improve the startup time of the extension.
142+ if ( userSettings == null )
143+ {
144+ client = uiProvider . GetService < IMetricsService > ( ) ;
145+ connectionManager = uiProvider . GetService < IConnectionManager > ( ) ;
146+ userSettings = uiProvider . GetService < IPackageSettings > ( ) ;
147+ vsservices = uiProvider . GetService < IVSServices > ( ) ;
148+
149+ var program = uiProvider . GetService < IProgram > ( ) ;
150+ storePath = System . IO . Path . Combine (
151+ Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ,
152+ program . ApplicationName ,
153+ StoreFileName ) ;
154+ }
155+ }
156+
148157 UsageStore LoadUsage ( )
149158 {
159+ Initialize ( ) ;
160+
150161 var json = fileExists ( storePath ) ? readAllText ( storePath , Encoding . UTF8 ) : null ;
151162 UsageStore result = null ;
152163 try
@@ -178,7 +189,6 @@ void RunTimer()
178189 {
179190 // The timer first ticks after 3 minutes to allow things to settle down after startup.
180191 // This will be changed to 8 hours after the first tick by the TimerTick method.
181- timer . Interval = TimeSpan . FromMinutes ( 3 ) ;
182192 timer . Start ( ) ;
183193 }
184194
@@ -194,21 +204,23 @@ void TimerTick(object sender, EventArgs e)
194204
195205 async Task TimerTick ( )
196206 {
197- Debug . Assert ( client != null , "TimerTick should not be triggered when there is no IMetricsService" ) ;
207+ Initialize ( ) ;
198208
199- // Subsequent timer ticks should occur every 8 hours.
200- timer . Interval = TimeSpan . FromHours ( 8 ) ;
209+ if ( firstRun )
210+ {
211+ IncrementLaunchCount ( ) ;
212+ timer . Interval = TimeSpan . FromHours ( 8 ) ;
213+ firstRun = false ;
214+ }
201215
202216 if ( userSettings == null )
203217 {
204218 await ThreadHelper . JoinableTaskFactory . SwitchToMainThreadAsync ( ) ;
205- client = serviceProvider . GetExportedValue < IMetricsService > ( ) ;
206219 if ( client == null )
207220 {
208221 timer . Stop ( ) ;
209222 return ;
210223 }
211- userSettings = serviceProvider . GetExportedValue < IPackageSettings > ( ) ;
212224 }
213225
214226 if ( ! userSettings . CollectMetrics )
0 commit comments