Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,23 @@ public async Task TaskWrapper_MemoryFootprint_IsSmallerThanObjects()
{
// This test demonstrates that structs don't allocate on the heap for the wrapper itself
// Only the TaskCompletionSource instances are heap-allocated

// Arrange & Act
GC.Collect();
var initialMemory = GC.GetTotalMemory(false);
Func<Task> taskFactory = static () => Task.CompletedTask;
var initialAllocatedBytes = GC.GetAllocatedBytesForCurrentThread();

var wrappers = new ActionTaskWrapper[1000];
for (int i = 0; i < wrappers.Length; i++)
{
// Only the TaskCompletionSource allocates on the heap, not the wrapper struct
wrappers[i] = new ActionTaskWrapper(() => Task.CompletedTask, new TaskCompletionSource());
wrappers[i] = new ActionTaskWrapper(taskFactory, new TaskCompletionSource());
}

var finalMemory = GC.GetTotalMemory(false);
var allocatedMemory = finalMemory - initialMemory;


var allocatedBytes = GC.GetAllocatedBytesForCurrentThread() - initialAllocatedBytes;

// Assert - Memory allocation should be only for TaskCompletionSource instances
// Each struct itself doesn't allocate heap memory
await Assert.That(allocatedMemory).IsLessThan(wrappers.Length * 200); // Conservative estimate
await Assert.That(allocatedBytes).IsLessThan(wrappers.Length * 200); // Conservative estimate
var hasNonNullFactory = wrappers[0].TaskFactory != null; // Prevent optimization
await Assert.That(hasNonNullFactory).IsTrue();
}
Expand Down
Loading