diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index aa1755ecb6..58e790d1fb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -90,6 +90,8 @@ private static readonly ConcurrentDictionary> _ColumnEncry capacity: 1, comparer: StringComparer.OrdinalIgnoreCase); + private static readonly Action s_openAsyncCancel = OpenAsyncCancel; + /// public static TimeSpan ColumnEncryptionKeyCacheTtl { get; set; } = TimeSpan.FromHours(2); @@ -1281,7 +1283,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) CancellationTokenRegistration registration = new CancellationTokenRegistration(); if (cancellationToken.CanBeCanceled) { - registration = cancellationToken.Register(s => ((TaskCompletionSource)s).TrySetCanceled(), completion); + registration = cancellationToken.Register(s_openAsyncCancel, completion); } OpenAsyncRetry retry = new OpenAsyncRetry(this, completion, result, registration); _currentCompletion = new Tuple, Task>(completion, result.Task); @@ -1302,6 +1304,11 @@ public override Task OpenAsync(CancellationToken cancellationToken) } } + private static void OpenAsyncCancel(object state) + { + ((TaskCompletionSource)state).TrySetCanceled(); + } + /// public override DataTable GetSchema() { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 0a6d80e7c7..2056a22b35 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -35,6 +35,8 @@ internal enum SnapshottedStateFlags : byte private const int AttentionTimeoutSeconds = 5; + private static readonly ContextCallback s_readAdyncCallbackComplete = ReadAsyncCallbackComplete; + // Ticks to consider a connection "good" after a successful I/O (10,000 ticks = 1 ms) // The resolution of the timer is typically in the range 10 to 16 milliseconds according to msdn. // We choose a value that is smaller than the likely timer resolution, but @@ -2824,7 +2826,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error) { if (_executionContext != null) { - ExecutionContext.Run(_executionContext, (state) => source.TrySetResult(null), null); + ExecutionContext.Run(_executionContext, s_readAdyncCallbackComplete, source); } else { @@ -2848,6 +2850,12 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error) } } + private static void ReadAsyncCallbackComplete(object state) + { + TaskCompletionSource source = (TaskCompletionSource)state; + source.TrySetResult(null); + } + protected abstract bool CheckPacket(PacketHandle packet, TaskCompletionSource source); private void ReadAsyncCallbackCaptureException(TaskCompletionSource source)