@@ -220,6 +220,67 @@ public async Task AddMetric_ReproduceFirstOrDefaultIssue_ShouldNotThrowException
220220 CleanupMetrics ( ) ;
221221 }
222222
223+ [ Fact ]
224+ public async Task AddMetric_ConcurrentModificationDuringIteration_ShouldHandleArgumentOutOfRangeException ( )
225+ {
226+ // Arrange
227+ Metrics . ResetForTest ( ) ;
228+ Metrics . SetNamespace ( "TestNamespace" ) ;
229+ var exceptions = new List < Exception > ( ) ;
230+ var tasks = new List < Task > ( ) ;
231+
232+ // Act - Create a scenario where collection modification happens during iteration
233+ // This test specifically targets the ArgumentOutOfRangeException catch block in GetExistingMetric
234+ for ( int i = 0 ; i < 20 ; i ++ )
235+ {
236+ var taskId = i ;
237+ tasks . Add ( Task . Run ( ( ) =>
238+ {
239+ try
240+ {
241+ // Rapidly add and flush metrics to create timing conditions
242+ // where GetExistingMetric might access an index that becomes invalid
243+ for ( int j = 0 ; j < 200 ; j ++ )
244+ {
245+ // Add metrics with the same key to trigger GetExistingMetric calls
246+ Metrics . AddMetric ( "SharedMetricKey" , 1.0 , MetricUnit . Count ) ;
247+
248+ // Occasionally add many metrics to trigger flush (which clears the collection)
249+ if ( j % 50 == 0 )
250+ {
251+ // Add enough metrics to trigger overflow and flush
252+ for ( int k = 0 ; k < 105 ; k ++ ) // Exceeds MaxMetrics (100)
253+ {
254+ Metrics . AddMetric ( $ "OverflowMetric_{ taskId } _{ k } ", 1.0 , MetricUnit . Count ) ;
255+ }
256+ }
257+ }
258+ }
259+ catch ( Exception ex )
260+ {
261+ lock ( exceptions )
262+ {
263+ exceptions . Add ( ex ) ;
264+ }
265+ }
266+ } ) ) ;
267+ }
268+
269+ await Task . WhenAll ( tasks ) ;
270+
271+ // Assert - Should not have any exceptions, even if ArgumentOutOfRangeException occurs internally
272+ foreach ( var ex in exceptions )
273+ {
274+ Console . WriteLine ( $ "Exception: { ex . GetType ( ) . Name } : { ex . Message } ") ;
275+ if ( ex . StackTrace != null )
276+ Console . WriteLine ( $ "Stack trace: { ex . StackTrace } ") ;
277+ }
278+ Assert . Empty ( exceptions ) ;
279+
280+ // Cleanup after test
281+ CleanupMetrics ( ) ;
282+ }
283+
223284 /// <summary>
224285 /// Cleanup method to ensure no state leaks between tests
225286 /// </summary>
0 commit comments