Skip to content

Commit f17bba2

Browse files
authored
Perf: Static delegates (#1060)
* netcore static lambda rework * minor netcore api cleanup * netfx static lambda rework * netcore add strongbox to avoid boxing * fixup 2 anonymous typed lambdas to be explicit
1 parent 1e8ce97 commit f17bba2

File tree

13 files changed

+561
-363
lines changed

13 files changed

+561
-363
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNILoadHandle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal class SNILoadHandle
1414
public static readonly SNILoadHandle SingletonInstance = new SNILoadHandle();
1515

1616
public readonly EncryptionOptions _encryptionOption = EncryptionOptions.OFF;
17-
public ThreadLocal<SNIError> _lastError = new ThreadLocal<SNIError>(() => { return new SNIError(SNIProviders.INVALID_PROV, 0, TdsEnums.SNI_SUCCESS, string.Empty); });
17+
public ThreadLocal<SNIError> _lastError = new ThreadLocal<SNIError>(static () => new SNIError(SNIProviders.INVALID_PROV, 0, TdsEnums.SNI_SUCCESS, string.Empty));
1818

1919
private readonly uint _status = TdsEnums.SNI_SUCCESS;
2020

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs

Lines changed: 105 additions & 78 deletions
Large diffs are not rendered by default.

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs

Lines changed: 97 additions & 92 deletions
Large diffs are not rendered by default.

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2152,7 +2152,7 @@ internal Task<T> RegisterForConnectionCloseNotification<T>(Task<T> outerTask, ob
21522152
{
21532153
// Connection exists, schedule removal, will be added to ref collection after calling ValidateAndReconnect
21542154
return outerTask.ContinueWith(
2155-
continuationFunction: (task, state) =>
2155+
continuationFunction: static (task, state) =>
21562156
{
21572157
Tuple<SqlConnection, object> parameters = (Tuple<SqlConnection, object>)state;
21582158
SqlConnection connection = parameters.Item1;

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ internal static Task CreateContinuationTask(Task task, Action onSuccess, Action<
3434
TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
3535
ContinueTaskWithState(task, completion,
3636
state: Tuple.Create(onSuccess, onFailure, completion),
37-
onSuccess: (state) =>
37+
onSuccess: static (object state) =>
3838
{
3939
var parameters = (Tuple<Action, Action<Exception>, TaskCompletionSource<object>>)state;
4040
Action success = parameters.Item1;
4141
TaskCompletionSource<object> taskCompletionSource = parameters.Item3;
4242
success();
4343
taskCompletionSource.SetResult(null);
4444
},
45-
onFailure: (exception, state) =>
45+
onFailure: static (Exception exception, object state) =>
4646
{
4747
var parameters = (Tuple<Action, Action<Exception>, TaskCompletionSource<object>>)state;
4848
Action<Exception> failure = parameters.Item2;
@@ -64,7 +64,7 @@ internal static Task CreateContinuationTaskWithState(Task task, object state, Ac
6464
{
6565
var completion = new TaskCompletionSource<object>();
6666
ContinueTaskWithState(task, completion, state,
67-
onSuccess: (continueState) =>
67+
onSuccess: (object continueState) =>
6868
{
6969
onSuccess(continueState);
7070
completion.SetResult(null);
@@ -81,12 +81,12 @@ internal static Task CreateContinuationTask<T1, T2>(Task task, Action<T1, T2> on
8181
}
8282

8383
internal static void ContinueTask(Task task,
84-
TaskCompletionSource<object> completion,
85-
Action onSuccess,
86-
Action<Exception> onFailure = null,
87-
Action onCancellation = null,
88-
Func<Exception, Exception> exceptionConverter = null
89-
)
84+
TaskCompletionSource<object> completion,
85+
Action onSuccess,
86+
Action<Exception> onFailure = null,
87+
Action onCancellation = null,
88+
Func<Exception, Exception> exceptionConverter = null
89+
)
9090
{
9191
task.ContinueWith(
9292
tsk =>
@@ -145,7 +145,7 @@ internal static void ContinueTaskWithState(Task task,
145145
)
146146
{
147147
task.ContinueWith(
148-
tsk =>
148+
(Task tsk, object state2) =>
149149
{
150150
if (tsk.Exception != null)
151151
{
@@ -156,7 +156,7 @@ internal static void ContinueTaskWithState(Task task,
156156
}
157157
try
158158
{
159-
onFailure?.Invoke(exc, state);
159+
onFailure?.Invoke(exc, state2);
160160
}
161161
finally
162162
{
@@ -167,7 +167,7 @@ internal static void ContinueTaskWithState(Task task,
167167
{
168168
try
169169
{
170-
onCancellation?.Invoke(state);
170+
onCancellation?.Invoke(state2);
171171
}
172172
finally
173173
{
@@ -178,14 +178,16 @@ internal static void ContinueTaskWithState(Task task,
178178
{
179179
try
180180
{
181-
onSuccess(state);
181+
onSuccess(state2);
182182
}
183183
catch (Exception e)
184184
{
185185
completion.SetException(e);
186186
}
187187
}
188-
}, TaskScheduler.Default
188+
},
189+
state: state,
190+
scheduler: TaskScheduler.Default
189191
);
190192
}
191193

@@ -205,25 +207,42 @@ internal static void WaitForCompletion(Task task, int timeout, Action onTimeout
205207
}
206208
if (!task.IsCompleted)
207209
{
208-
task.ContinueWith(t => { var ignored = t.Exception; }); //Ensure the task does not leave an unobserved exception
209-
if (onTimeout != null)
210-
{
211-
onTimeout();
212-
}
210+
task.ContinueWith(static t => { var ignored = t.Exception; }); //Ensure the task does not leave an unobserved exception
211+
onTimeout?.Invoke();
213212
}
214213
}
215214

216-
internal static void SetTimeoutException(TaskCompletionSource<object> completion, int timeout, Func<Exception> exc, CancellationToken ctoken)
215+
internal static void SetTimeoutException(TaskCompletionSource<object> completion, int timeout, Func<Exception> onFailure, CancellationToken ctoken)
217216
{
218217
if (timeout > 0)
219218
{
220-
Task.Delay(timeout * 1000, ctoken).ContinueWith((tsk) =>
221-
{
222-
if (!tsk.IsCanceled && !completion.Task.IsCompleted)
219+
Task.Delay(timeout * 1000, ctoken).ContinueWith(
220+
(Task task) =>
223221
{
224-
completion.TrySetException(exc());
222+
if (!task.IsCanceled && !completion.Task.IsCompleted)
223+
{
224+
completion.TrySetException(onFailure());
225+
}
225226
}
226-
});
227+
);
228+
}
229+
}
230+
231+
internal static void SetTimeoutExceptionWithState(TaskCompletionSource<object> completion, int timeout, object state, Func<object,Exception> onFailure, CancellationToken cancellationToken)
232+
{
233+
if (timeout > 0)
234+
{
235+
Task.Delay(timeout * 1000, cancellationToken).ContinueWith(
236+
(Task task, object state) =>
237+
{
238+
if (!task.IsCanceled && !completion.Task.IsCompleted)
239+
{
240+
completion.TrySetException(onFailure(state));
241+
}
242+
},
243+
state: state,
244+
cancellationToken: CancellationToken.None
245+
);
227246
}
228247
}
229248
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8842,7 +8842,7 @@ internal Task TdsExecuteSQLBatch(string text, int timeout, SqlNotificationReques
88428842
bool taskReleaseConnectionLock = releaseConnectionLock;
88438843
releaseConnectionLock = false;
88448844
return executeTask.ContinueWith(
8845-
(task, state) =>
8845+
static (Task task, object state) =>
88468846
{
88478847
Debug.Assert(!task.IsCanceled, "Task should not be canceled");
88488848
var parameters = (Tuple<TdsParser, TdsParserStateObject, SqlInternalConnectionTds>)state;
@@ -9068,7 +9068,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, int timeout, boo
90689068
if (releaseConnectionLock)
90699069
{
90709070
task.ContinueWith(
9071-
(_, state) => ((SqlInternalConnectionTds)state)._parserLock.Release(),
9071+
static (Task _, object state) => ((SqlInternalConnectionTds)state)._parserLock.Release(),
90729072
state: _connHandler,
90739073
TaskScheduler.Default
90749074
);

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,16 @@ internal Task ExecuteFlush()
10161016
}
10171017
else
10181018
{
1019-
return AsyncHelper.CreateContinuationTask(writePacketTask, () => { HasPendingData = true; _messageStatus = 0; });
1019+
return AsyncHelper.CreateContinuationTaskWithState(
1020+
task: writePacketTask,
1021+
state: this,
1022+
onSuccess: static (object state) =>
1023+
{
1024+
TdsParserStateObject stateObject = (TdsParserStateObject)state;
1025+
stateObject.HasPendingData = true;
1026+
stateObject._messageStatus = 0;
1027+
}
1028+
);
10201029
}
10211030
}
10221031
}

0 commit comments

Comments
 (0)