@@ -163,21 +163,37 @@ private void ProbeLoop(object? state)
163163 {
164164 try
165165 {
166- // Pause probing if Slow Request simulation is running
167- // This prevents the probes from flooding the thread pool and dominating logs/traces
168- if ( _simulationTracker . GetActiveCountByType ( Models . SimulationType . SlowRequest ) > 0 )
166+ // Check if Slow Request simulation is running
167+ bool isSlowRequestActive = _simulationTracker . GetActiveCountByType ( Models . SimulationType . SlowRequest ) > 0 ;
168+
169+ // If Slow Request simulation is running, we slow down the probe frequency DRAMATICALLY
170+ // but we DO NOT stop it completely.
171+ //
172+ // Why?
173+ // 1. If we stop completely, the CLR Profiler often fails to record the "Request Finished" event
174+ // for the slow request because the server becomes too quiet/idle, and ETW buffers don't flush.
175+ // This results in "No events emitted" warnings and "Status: 0, Duration: [Infinite]" in traces.
176+ // 2. By keeping a "heartbeat" (e.g., every 5 seconds), we generate just enough activity
177+ // to keep the trace pipeline alive without creating significant noise or contention.
178+
179+ if ( isSlowRequestActive )
169180 {
170- Thread . Sleep ( 500 ) ; // Check again in 500ms
171- continue ;
181+ // Run sparsely: Wait 5 seconds between probes instead of 100ms
182+ Thread . Sleep ( 5000 ) ;
172183 }
173184
174185 var result = MeasureLatency ( httpClient , cancellationToken ) ;
175186
176187 // Broadcast to all connected clients
188+ // Note: The UI filters out / hides the probe graph during slow request mode,
189+ // so these rare updates won't distract the user visually.
177190 BroadcastLatency ( result ) ;
178191
179- // Wait for next probe interval
180- Thread . Sleep ( ProbeIntervalMs ) ;
192+ // Normal interval wait
193+ if ( ! isSlowRequestActive )
194+ {
195+ Thread . Sleep ( ProbeIntervalMs ) ;
196+ }
181197 }
182198 catch ( OperationCanceledException ) when ( cancellationToken . IsCancellationRequested )
183199 {
0 commit comments