Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit ec2dd18

Browse files
committed
rework SqlDataReader retryable to resumable
1 parent 4ff66e5 commit ec2dd18

File tree

2 files changed

+523
-264
lines changed

2 files changed

+523
-264
lines changed

src/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommand.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public sealed partial class SqlCommand : DbCommand, ICloneable
3131
private static readonly DiagnosticListener _diagnosticListener = new DiagnosticListener(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName);
3232
private bool _parentOperationStarted = false;
3333

34+
internal static readonly Action<object> s_cancelIgnoreFailure = CancelIgnoreFailureCallback;
35+
3436
// Prepare
3537
// Against 7.0 Serve a prepare/unprepare requires an extra roundtrip to the server.
3638
//
@@ -1184,7 +1186,7 @@ private Task InternalExecuteNonQuery(TaskCompletionSource<object> completion, bo
11841186
if (task != null)
11851187
{
11861188
task = AsyncHelper.CreateContinuationTaskWithState(task,
1187-
state: reader,
1189+
state: reader,
11881190
onSuccess: state => ((SqlDataReader)state).Close()
11891191
);
11901192
}
@@ -1644,7 +1646,7 @@ public override Task<int> ExecuteNonQueryAsync(CancellationToken cancellationTok
16441646
source.SetCanceled();
16451647
return source.Task;
16461648
}
1647-
registration = cancellationToken.Register(s => ((SqlCommand)s).CancelIgnoreFailure(), this);
1649+
registration = cancellationToken.Register(s_cancelIgnoreFailure, this);
16481650
}
16491651

16501652
Task<int> returnedTask = source.Task;
@@ -1727,7 +1729,7 @@ protected override Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior b
17271729
source.SetCanceled();
17281730
return source.Task;
17291731
}
1730-
registration = cancellationToken.Register(s => ((SqlCommand)s).CancelIgnoreFailure(), this);
1732+
registration = cancellationToken.Register(s_cancelIgnoreFailure, this);
17311733
}
17321734

17331735
Task<SqlDataReader> returnedTask = source.Task;
@@ -1872,7 +1874,7 @@ public Task<XmlReader> ExecuteXmlReaderAsync(CancellationToken cancellationToken
18721874
source.SetCanceled();
18731875
return source.Task;
18741876
}
1875-
registration = cancellationToken.Register(s => ((SqlCommand)s).CancelIgnoreFailure(), this);
1877+
registration = cancellationToken.Register(s_cancelIgnoreFailure, this);
18761878
}
18771879

18781880
Task<XmlReader> returnedTask = source.Task;
@@ -2458,7 +2460,7 @@ private void RunExecuteNonQueryTdsSetupReconnnectContinuation(string methodName,
24582460
}
24592461
else
24602462
{
2461-
AsyncHelper.ContinueTaskWithState(subTask, completion,
2463+
AsyncHelper.ContinueTaskWithState(subTask, completion,
24622464
state: completion,
24632465
onSuccess: (state) => ((TaskCompletionSource<object>)state).SetResult(null)
24642466
);
@@ -2713,7 +2715,7 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi
27132715
// This is in its own method to avoid always allocating the lambda in RunExecuteReaderTds
27142716
private Task RunExecuteReaderTdsSetupContinuation(RunBehavior runBehavior, SqlDataReader ds, string optionSettings, Task writeTask)
27152717
{
2716-
Task task = AsyncHelper.CreateContinuationTask(writeTask,
2718+
Task task = AsyncHelper.CreateContinuationTask(writeTask,
27172719
onSuccess: () =>
27182720
{
27192721
_activeConnection.GetOpenTdsConnection(); // it will throw if connection is closed
@@ -2749,7 +2751,7 @@ private void RunExecuteReaderTdsSetupReconnectContinuation(CommandBehavior cmdBe
27492751
}
27502752
else
27512753
{
2752-
AsyncHelper.ContinueTaskWithState(subTask, completion,
2754+
AsyncHelper.ContinueTaskWithState(subTask, completion,
27532755
state: completion,
27542756
onSuccess: (state) => ((TaskCompletionSource<object>)state).SetResult(null)
27552757
);
@@ -4019,6 +4021,12 @@ internal void CompletePendingReadWithFailure(int errorCode, bool resetForcePendi
40194021
}
40204022
#endif
40214023

4024+
internal static void CancelIgnoreFailureCallback(object state)
4025+
{
4026+
SqlCommand command = (SqlCommand)state;
4027+
command.CancelIgnoreFailure();
4028+
}
4029+
40224030
internal void CancelIgnoreFailure()
40234031
{
40244032
// This method is used to route CancellationTokens to the Cancel method.

0 commit comments

Comments
 (0)