@@ -49,10 +49,8 @@ private TelemetryManager()
4949 /// versus integrated mode (e.g., running within Visual Studio or dotnet CLI).
5050 /// When <c>true</c>, creates and manages its own telemetry session on .NET Framework.
5151 /// </param>
52- /// <param name="isTelemetryExplicitlyRequested">
53- /// Indicates whether telemetry was explicitly requested through command line arguments.
54- /// </param>
55- public void Initialize ( bool isStandalone , bool isTelemetryExplicitlyRequested )
52+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
53+ public void Initialize ( bool isStandalone )
5654 {
5755 lock ( s_lock )
5856 {
@@ -68,7 +66,7 @@ public void Initialize(bool isStandalone, bool isTelemetryExplicitlyRequested)
6866 return ;
6967 }
7068
71- TryInitializeTelemetry ( isStandalone , isTelemetryExplicitlyRequested ) ;
69+ TryInitializeTelemetry ( isStandalone ) ;
7270 }
7371 }
7472
@@ -92,14 +90,14 @@ internal static void ResetForTest()
9290 /// allowing the calling code to catch assembly loading exceptions.
9391 /// </summary>
9492 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
95- private void TryInitializeTelemetry ( bool isStandalone , bool isTelemetryExplicitlyRequested )
93+ private void TryInitializeTelemetry ( bool isStandalone )
9694 {
9795 try
9896 {
9997#if NETFRAMEWORK
10098 DefaultActivitySource = VsTelemetryInitializer . Initialize ( isStandalone ) ;
10199#else
102- DefaultActivitySource = new MSBuildActivitySource ( TelemetryConstants . DefaultActivitySourceNamespace , isTelemetryExplicitlyRequested ) ;
100+ DefaultActivitySource = new MSBuildActivitySource ( TelemetryConstants . DefaultActivitySourceNamespace ) ;
103101#endif
104102 }
105103 catch ( Exception ex ) when ( ex is FileNotFoundException or FileLoadException or TypeLoadException )
@@ -136,65 +134,58 @@ FileLoadException or
136134 }
137135 }
138136
139- #if NETFRAMEWORK
140- [ MethodImpl ( MethodImplOptions . NoInlining ) ]
141- private static void DisposeVsTelemetry ( ) => VsTelemetryInitializer . Dispose ( ) ;
142- #endif
143-
144137 /// <summary>
145138 /// Determines if the user has explicitly opted out of telemetry.
146139 /// </summary>
147- private static bool IsOptOut ( ) =>
140+ internal static bool IsOptOut ( ) =>
148141#if NETFRAMEWORK
149142 Traits . Instance . FrameworkTelemetryOptOut ;
150143#else
151144 Traits . Instance . SdkTelemetryOptOut ;
152145#endif
146+
147+ #if NETFRAMEWORK
148+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
149+ private static void DisposeVsTelemetry ( ) => VsTelemetryInitializer . Dispose ( ) ;
150+ #endif
153151 }
154152
155153#if NETFRAMEWORK
156- /// <summary>
157- /// Isolated class that references Microsoft.VisualStudio.Telemetry types.
158- /// This separation ensures the VS Telemetry assembly is only loaded when methods
159- /// on this class are actually invoked.
160- /// </summary>
161- /// <remarks>
162- /// Thread-safety: All public methods on this class must be called under the
163- /// <see cref="TelemetryManager"/> lock to ensure thread-safe access to static state.
164- /// Callers must not invoke <see cref="Initialize"/> or <see cref="Dispose"/> concurrently.
165- /// </remarks>
166154 internal static class VsTelemetryInitializer
167155 {
168156 // Telemetry API key for Visual Studio telemetry service.
169157 private const string CollectorApiKey = "f3e86b4023cc43f0be495508d51f588a-f70d0e59-0fb0-4473-9f19-b4024cc340be-7296" ;
170158
171- private static TelemetrySession ? s_telemetrySession ;
159+ // Store as object to avoid type reference at class load time
160+ private static object ? s_telemetrySession ;
172161 private static bool s_ownsSession = false ;
173162
163+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
174164 public static MSBuildActivitySource Initialize ( bool isStandalone )
175165 {
166+ TelemetrySession session ;
176167 if ( isStandalone )
177168 {
178- s_telemetrySession = TelemetryService . CreateAndGetDefaultSession ( CollectorApiKey ) ;
169+ session = TelemetryService . CreateAndGetDefaultSession ( CollectorApiKey ) ;
179170 TelemetryService . DefaultSession . UseVsIsOptedIn ( ) ;
180171 TelemetryService . DefaultSession . Start ( ) ;
181172 s_ownsSession = true ;
182173 }
183174 else
184175 {
185- s_telemetrySession = TelemetryService . DefaultSession ;
176+ session = TelemetryService . DefaultSession ;
186177 }
187178
188- return new MSBuildActivitySource ( s_telemetrySession ) ;
179+ s_telemetrySession = session ;
180+ return new MSBuildActivitySource ( session ) ;
189181 }
190182
183+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
191184 public static void Dispose ( )
192185 {
193- // Only dispose the session if we created it (standalone scenario).
194- // In VS, the session is owned by VS and should not be disposed by MSBuild.
195- if ( s_ownsSession )
186+ if ( s_ownsSession && s_telemetrySession is TelemetrySession session )
196187 {
197- s_telemetrySession ? . Dispose ( ) ;
188+ session . Dispose ( ) ;
198189 }
199190
200191 s_telemetrySession = null ;
0 commit comments