From c4ce88c39358ec2143cfb9975822699e5c7423a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 5 Jul 2026 21:35:44 +0200 Subject: [PATCH] perf: skip TCS bridge in ExecuteTestAsync when no ExecutionContext is captured In the common case (tests whose [ClassInitialize] / [AssemblyInitialize] did not capture an ExecutionContext), ExecutionContextHelpers.RunOnContext simply calls the action inline. The existing code still allocated a TaskCompletionSource, an async-lambda closure, and an Action delegate for every test even when unnecessary. Add a fast path that skips all three allocations when the captured context is null. The slow path (TCS bridge via ExecutionContext.Run) is preserved unchanged for the rare case where a lifecycle method captured a context. Fixes #9635 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Execution/TestMethodRunner.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodRunner.cs b/src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodRunner.cs index 1c11cf658f..849b6ba9b1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodRunner.cs @@ -496,11 +496,27 @@ private async Task ExecuteTestAsync(ITestContext executionContext, { try { + ExecutionContext? capturedContext = testMethodInfo.Parent.ExecutionContext + ?? testMethodInfo.Parent.Parent.ExecutionContext; + + // Fast path: when no ExecutionContext was captured (the common case), + // ExecutionContextHelpers.RunOnContext would simply call the action inline. + // Skip the TaskCompletionSource bridge, async-lambda closure, and Action + // delegate allocations entirely. + if (capturedContext is null) + { + using (TestContextImplementation.SetCurrentTestContext(executionContext as TestContext)) + { + testMethodInfo.TestContext = executionContext; + return await _testMethodInfo.Executor.ExecuteAsync(testMethodInfo).ConfigureAwait(false); + } + } + var tcs = new TaskCompletionSource(); #pragma warning disable VSTHRD101 // Avoid unsupported async delegates ExecutionContextHelpers.RunOnContext( - testMethodInfo.Parent.ExecutionContext ?? testMethodInfo.Parent.Parent.ExecutionContext, + capturedContext, async () => { try