From b18c59a2671ebaec30e5a2c81a3910f4365ad7ec Mon Sep 17 00:00:00 2001 From: electricessence <5899455+electricessence@users.noreply.github.com> Date: Tue, 10 Nov 2026 17:55:47 -0800 Subject: [PATCH] Async readers are disposed with ConfigureAwait(false) On netstandard2.1 and net10.0 the reader was disposed with a plain 'await using', so its DisposeAsync resumed on the caller's context. Each one now uses the same form as Transaction.cs. Co-Authored-By: Claude Opus 5.5 --- Source/Core/ExpressiveCommandBase.cs | 5 ++-- Source/Core/Extensions/Command._.cs | 45 +++++++++++++++++----------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/Source/Core/ExpressiveCommandBase.cs b/Source/Core/ExpressiveCommandBase.cs index 16e4c01..1ffd38f 100644 --- a/Source/Core/ExpressiveCommandBase.cs +++ b/Source/Core/ExpressiveCommandBase.cs @@ -1047,10 +1047,11 @@ ValueTask ExecuteReaderCoreAsync(TState state, Func> ToListAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); return await reader.ToListAsync(transform, cancellationToken).ConfigureAwait(false); } @@ -182,10 +183,11 @@ public static async ValueTask> ToListAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); if (useReadAsync) return await reader.ToListAsync(transform, cancellationToken).ConfigureAwait(false); @@ -346,10 +348,11 @@ public static async ValueTask ExecuteReaderAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); handler(reader); } @@ -395,10 +398,11 @@ public static async ValueTask ExecuteReaderAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); await handler(reader).ConfigureAwait(false); } @@ -421,10 +425,11 @@ public static async ValueTask ExecuteReaderAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); return transform(reader); } @@ -464,10 +469,11 @@ public static async ValueTask ExecuteReaderAsync(this DbCommand command, Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); return await transform(reader).ConfigureAwait(false); } @@ -585,10 +591,11 @@ public static async ValueTask ForEachAsync(this DbCommand command, cancellationToken.ThrowIfCancellationRequested(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); await reader.ForEachAsync(handler, useReadAsync, cancellationToken).ConfigureAwait(false); } @@ -612,10 +619,11 @@ public static async ValueTask ForEachAsync(this DbCommand command, cancellationToken.ThrowIfCancellationRequested(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); await reader.ForEachAsync(handler, useReadAsync, cancellationToken).ConfigureAwait(false); } @@ -641,10 +649,11 @@ public static async ValueTask IterateReaderWhileAsync(this DbCommand command, Fu Contract.EndContractBlock(); #if NETSTANDARD2_0 + using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); #else - await + DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); + await using var readerDisposal = reader.ConfigureAwait(false); #endif - using DbDataReader reader = await command.OpenAndExecuteReaderAsync(behavior, cancellationToken).ConfigureAwait(false); await reader.IterateWhileAsync(predicate, useReadAsync, cancellationToken).ConfigureAwait(false); }