11using System . Collections . Concurrent ;
2+ using System . Collections . Immutable ;
23using System . Diagnostics . CodeAnalysis ;
34using TUnit . Core . Helpers ;
45
@@ -48,12 +49,17 @@ private static Counter GetOrCreateCounter(object obj) =>
4849 s_trackedObjects . GetOrAdd ( obj , static _ => new Counter ( ) ) ;
4950
5051 /// <summary>
51- /// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single HashSet .
52+ /// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single ISet .
5253 /// Thread-safe: locks each HashSet while copying.
5354 /// Pre-calculates capacity to avoid HashSet resizing during population.
5455 /// </summary>
55- private static HashSet < object > FlattenTrackedObjects ( ConcurrentDictionary < int , HashSet < object > > trackedObjects )
56+ private static ISet < object > FlattenTrackedObjects ( ConcurrentDictionary < int , HashSet < object > > trackedObjects )
5657 {
58+ if ( trackedObjects . IsEmpty )
59+ {
60+ return ImmutableHashSet < object > . Empty ;
61+ }
62+
5763#if NETSTANDARD2_0
5864 // .NET Standard 2.0 doesn't support HashSet capacity constructor
5965 var result = new HashSet < object > ( Helpers . ReferenceEqualityComparer . Instance ) ;
@@ -91,8 +97,13 @@ public void TrackObjects(TestContext testContext)
9197 var alreadyTracked = FlattenTrackedObjects ( testContext . TrackedObjects ) ;
9298
9399 // Get new trackable objects
94- var newTrackableObjects = new HashSet < object > ( Helpers . ReferenceEqualityComparer . Instance ) ;
95100 var trackableDict = trackableObjectGraphProvider . GetTrackableObjects ( testContext ) ;
101+ if ( trackableDict . IsEmpty && alreadyTracked . Count == 0 )
102+ {
103+ return ;
104+ }
105+
106+ var newTrackableObjects = new HashSet < object > ( Helpers . ReferenceEqualityComparer . Instance ) ;
96107 foreach ( var kvp in trackableDict )
97108 {
98109 lock ( kvp . Value )
@@ -113,11 +124,20 @@ public void TrackObjects(TestContext testContext)
113124 }
114125 }
115126
116- public async ValueTask UntrackObjects ( TestContext testContext , List < Exception > cleanupExceptions )
127+ public ValueTask UntrackObjects ( TestContext testContext , List < Exception > cleanupExceptions )
117128 {
118129 // Get all objects to untrack (DRY: use helper method)
119130 var objectsToUntrack = FlattenTrackedObjects ( testContext . TrackedObjects ) ;
131+ if ( objectsToUntrack . Count == 0 )
132+ {
133+ return ValueTask . CompletedTask ;
134+ }
120135
136+ return UntrackObjectsAsync ( cleanupExceptions , objectsToUntrack ) ;
137+ }
138+
139+ private async ValueTask UntrackObjectsAsync ( List < Exception > cleanupExceptions , ISet < object > objectsToUntrack )
140+ {
121141 foreach ( var obj in objectsToUntrack )
122142 {
123143 try
0 commit comments