Skip to content

Commit 259c059

Browse files
authored
Replace Thread.Sleep with await Task.Delay (#48)
1 parent 37a413e commit 259c059

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

src/SqlSessionStateProviderAsync/SqlInMemoryTableSessionStateRepository.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Microsoft.AspNet.SessionState
77
using System;
88
using System.Data.SqlClient;
99
using System.Diagnostics;
10+
using System.Runtime.CompilerServices;
1011
using System.Threading;
1112
using System.Threading.Tasks;
1213
using System.Web;
@@ -316,7 +317,7 @@ public void CreateSessionStateTable()
316317
try
317318
{
318319
var cmd = _commandHelper.CreateNewSessionTableCmd(CreateSessionTableSql);
319-
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry).ConfigureAwait(false);
320+
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync).ConfigureAwait(false);
320321
task.GetAwaiter().GetResult();
321322
}
322323
catch (Exception ex)
@@ -343,7 +344,7 @@ public void DeleteExpiredSessions()
343344
using (var connection = new SqlConnection(_connectString))
344345
{
345346
var cmd = _commandHelper.CreateDeleteExpiredSessionsCmd(DeleteExpiredSessionsSql);
346-
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry).ConfigureAwait(false);
347+
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync).ConfigureAwait(false);
347348
task.GetAwaiter().GetResult();
348349
}
349350
}
@@ -369,7 +370,7 @@ public async Task<SessionItem> GetSessionStateItemAsync(string id, bool exclusiv
369370

370371
using (var connection = new SqlConnection(_connectString))
371372
{
372-
using (var reader = await SqlSessionStateRepositoryUtil.SqlExecuteReaderWithRetryAsync(connection, cmd, CanRetry))
373+
using (var reader = await SqlSessionStateRepositoryUtil.SqlExecuteReaderWithRetryAsync(connection, cmd, CanRetryAsync))
373374
{
374375
if (await reader.ReadAsync())
375376
{
@@ -419,7 +420,7 @@ public async Task CreateOrUpdateSessionStateItemAsync(bool newItem, string id,
419420

420421
using (var connection = new SqlConnection(_connectString))
421422
{
422-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry, newItem);
423+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync, newItem);
423424
}
424425
}
425426

@@ -428,7 +429,7 @@ public async Task ResetSessionItemTimeoutAsync(string id)
428429
var cmd = _commandHelper.CreateResetItemTimeoutCmd(ResetItemTimeoutSql, id);
429430
using (var connection = new SqlConnection(_connectString))
430431
{
431-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
432+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
432433
}
433434
}
434435

@@ -437,7 +438,7 @@ public async Task RemoveSessionItemAsync(string id, object lockId)
437438
var cmd = _commandHelper.CreateRemoveStateItemCmd(RemoveStateItemSql, id, lockId);
438439
using (var connection = new SqlConnection(_connectString))
439440
{
440-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
441+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
441442
}
442443
}
443444

@@ -446,7 +447,7 @@ public async Task ReleaseSessionItemAsync(string id, object lockId)
446447
var cmd = _commandHelper.CreateReleaseItemExclusiveCmd(ReleaseItemExclusiveSql, id, lockId);
447448
using (var connection = new SqlConnection(_connectString))
448449
{
449-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
450+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
450451
}
451452
}
452453

@@ -455,26 +456,33 @@ public async Task CreateUninitializedSessionItemAsync(string id, int length, byt
455456
var cmd = _commandHelper.CreateTempInsertUninitializedItemCmd(TempInsertUninitializedItemSql, id, length, buf, timeout);
456457
using (var connection = new SqlConnection(_connectString))
457458
{
458-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry, true);
459+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync, true);
459460
}
460461
}
461462

462-
private bool CanRetry(RetryCheckParameter parameter)
463+
private Task<bool> CanRetryAsync(RetryCheckParameter parameter)
463464
{
464465
if (parameter.RetryCount >= _maxRetryNum ||
465466
!ShouldUseInMemoryTableRetry(parameter.Exception))
466467
{
467-
return false;
468+
return Task.FromResult(false);
468469
}
469470

471+
return WaitToRetryAsync(parameter, _retryIntervalMilSec);
472+
}
473+
474+
[MethodImpl(MethodImplOptions.NoInlining)]
475+
private static async Task<bool> WaitToRetryAsync(RetryCheckParameter parameter, int retryIntervalMilSec)
476+
{
470477
// this actually may sleep up to 15ms
471478
// but it's better than spinning CPU
472-
Thread.Sleep(_retryIntervalMilSec);
479+
await Task.Delay(retryIntervalMilSec);
473480
parameter.RetryCount++;
474481

475482
return true;
476483
}
477484

485+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
478486
private bool ShouldUseInMemoryTableRetry(SqlException ex)
479487
{
480488
// Error code is defined on

src/SqlSessionStateProviderAsync/SqlSessionStateRepository.cs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Microsoft.AspNet.SessionState
66
using Resources;
77
using System;
88
using System.Data.SqlClient;
9-
using System.Threading;
9+
using System.Runtime.CompilerServices;
1010
using System.Threading.Tasks;
1111
using System.Web;
1212
using System.Web.SessionState;
@@ -47,10 +47,10 @@ Created datetime NOT NULL DEFAULT GETUTCDATE(),
4747
)
4848
CREATE NONCLUSTERED INDEX Index_Expires ON {SqlSessionStateRepositoryUtil.TableName} (Expires)
4949
END";
50-
#endregion
50+
#endregion
5151

5252
#region TempInsertUninitializedItem
53-
private static readonly string TempInsertUninitializedItemSql = $@"
53+
private static readonly string TempInsertUninitializedItemSql = $@"
5454
DECLARE @now AS datetime
5555
DECLARE @nowLocal AS datetime
5656
SET @now = GETUTCDATE()
@@ -75,10 +75,10 @@ DECLARE @nowLocal AS datetime
7575
@nowLocal,
7676
1,
7777
1)";
78-
#endregion
78+
#endregion
7979

8080
#region GetStateItemExclusive
81-
private static readonly string GetStateItemExclusiveSql = $@"
81+
private static readonly string GetStateItemExclusiveSql = $@"
8282
BEGIN TRAN
8383
DECLARE @textptr AS varbinary(16)
8484
DECLARE @length AS int
@@ -275,7 +275,7 @@ DEALLOCATE ExpiredSessionCursor
275275
END
276276
277277
DROP TABLE #tblExpiredSessions";
278-
#endregion
278+
#endregion
279279
#endregion
280280

281281
public SqlSessionStateRepository(string connectionString, int commandTimeout,
@@ -310,17 +310,23 @@ internal int CommandTimeout
310310
}
311311
#endregion
312312

313-
private bool CanRetry(RetryCheckParameter parameter)
313+
private Task<bool> CanRetryAsync(RetryCheckParameter parameter)
314314
{
315315
if (_retryIntervalMilSec <= 0 ||
316316
!SqlSessionStateRepositoryUtil.IsFatalSqlException(parameter.Exception) ||
317317
parameter.RetryCount >= _maxRetryNum)
318318
{
319-
return false;
319+
return Task.FromResult(false);
320320
}
321321

322+
return WaitToRetryAsync(parameter, _retryIntervalMilSec);
323+
}
324+
325+
[MethodImpl(MethodImplOptions.NoInlining)]
326+
private static async Task<bool> WaitToRetryAsync(RetryCheckParameter parameter, int retryIntervalMilSec)
327+
{
322328
// sleep the specified time and allow retry
323-
Thread.Sleep(_retryIntervalMilSec);
329+
await Task.Delay(retryIntervalMilSec);
324330
parameter.RetryCount++;
325331

326332
return true;
@@ -334,7 +340,7 @@ public void CreateSessionStateTable()
334340
try
335341
{
336342
var cmd = _commandHelper.CreateNewSessionTableCmd(CreateSessionTableSql);
337-
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry).ConfigureAwait(false);
343+
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync).ConfigureAwait(false);
338344
task.GetAwaiter().GetResult();
339345
}
340346
catch (Exception ex)
@@ -349,7 +355,7 @@ public void DeleteExpiredSessions()
349355
using (var connection = new SqlConnection(_connectString))
350356
{
351357
var cmd = _commandHelper.CreateDeleteExpiredSessionsCmd(DeleteExpiredSessionsSql);
352-
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry).ConfigureAwait(false);
358+
var task = SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync).ConfigureAwait(false);
353359
task.GetAwaiter().GetResult();
354360
}
355361
}
@@ -375,7 +381,7 @@ public async Task<SessionItem> GetSessionStateItemAsync(string id, bool exclusiv
375381

376382
using (var connection = new SqlConnection(_connectString))
377383
{
378-
using (var reader = await SqlSessionStateRepositoryUtil.SqlExecuteReaderWithRetryAsync(connection, cmd, CanRetry))
384+
using (var reader = await SqlSessionStateRepositoryUtil.SqlExecuteReaderWithRetryAsync(connection, cmd, CanRetryAsync))
379385
{
380386
if (await reader.ReadAsync())
381387
{
@@ -427,7 +433,7 @@ public async Task CreateOrUpdateSessionStateItemAsync(bool newItem, string id, b
427433

428434
using (var connection = new SqlConnection(_connectString))
429435
{
430-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry, newItem);
436+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync, newItem);
431437
}
432438
}
433439

@@ -436,7 +442,7 @@ public async Task ResetSessionItemTimeoutAsync(string id)
436442
var cmd = _commandHelper.CreateResetItemTimeoutCmd(ResetItemTimeoutSql, id);
437443
using (var connection = new SqlConnection(_connectString))
438444
{
439-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
445+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
440446
}
441447
}
442448

@@ -445,7 +451,7 @@ public async Task RemoveSessionItemAsync(string id, object lockId)
445451
var cmd = _commandHelper.CreateRemoveStateItemCmd(RemoveStateItemSql, id, lockId);
446452
using (var connection = new SqlConnection(_connectString))
447453
{
448-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
454+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
449455
}
450456
}
451457

@@ -454,7 +460,7 @@ public async Task ReleaseSessionItemAsync(string id, object lockId)
454460
var cmd = _commandHelper.CreateReleaseItemExclusiveCmd(ReleaseItemExclusiveSql, id, lockId);
455461
using (var connection = new SqlConnection(_connectString))
456462
{
457-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry);
463+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync);
458464
}
459465
}
460466

@@ -463,10 +469,10 @@ public async Task CreateUninitializedSessionItemAsync(string id, int length, byt
463469
var cmd = _commandHelper.CreateTempInsertUninitializedItemCmd(TempInsertUninitializedItemSql, id, length, buf, timeout);
464470
using (var connection = new SqlConnection(_connectString))
465471
{
466-
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetry, true);
472+
await SqlSessionStateRepositoryUtil.SqlExecuteNonQueryWithRetryAsync(connection, cmd, CanRetryAsync, true);
467473
}
468474
}
469475
#endregion
470-
471-
}
476+
477+
}
472478
}

src/SqlSessionStateProviderAsync/SqlSessionStateRepositoryUtil.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Microsoft.AspNet.SessionState
77
using System;
88
using System.Data;
99
using System.Data.SqlClient;
10+
using System.Runtime.CompilerServices;
1011
using System.Security.Principal;
1112
using System.Threading.Tasks;
1213
using System.Web;
@@ -61,7 +62,7 @@ class SqlSessionStateRepositoryUtil
6162
public static readonly int DefaultItemLength = 7000;
6263

6364
public static async Task<int> SqlExecuteNonQueryWithRetryAsync(SqlConnection connection, SqlCommand sqlCmd,
64-
Func<RetryCheckParameter, bool> canRetry, bool ignoreInsertPKException = false)
65+
Func<RetryCheckParameter, Task<bool>> canRetry, bool ignoreInsertPKException = false)
6566
{
6667
var retryParamenter = new RetryCheckParameter() { EndRetryTime = DateTime.UtcNow, RetryCount = 0 };
6768
sqlCmd.Connection = connection;
@@ -84,15 +85,15 @@ public static async Task<int> SqlExecuteNonQueryWithRetryAsync(SqlConnection con
8485
}
8586

8687
retryParamenter.Exception = e;
87-
if (!canRetry(retryParamenter))
88+
if (!(await canRetry(retryParamenter)))
8889
{
8990
throw;
9091
}
9192
}
9293
}
9394
}
9495

95-
public static async Task<SqlDataReader> SqlExecuteReaderWithRetryAsync(SqlConnection connection, SqlCommand sqlCmd, Func<RetryCheckParameter, bool> canRetry,
96+
public static async Task<SqlDataReader> SqlExecuteReaderWithRetryAsync(SqlConnection connection, SqlCommand sqlCmd, Func<RetryCheckParameter, Task<bool>> canRetry,
9697
CommandBehavior cmdBehavior = CommandBehavior.Default)
9798
{
9899
var retryParamenter = new RetryCheckParameter() { EndRetryTime = DateTime.UtcNow, RetryCount = 0 };
@@ -109,14 +110,15 @@ public static async Task<SqlDataReader> SqlExecuteReaderWithRetryAsync(SqlConnec
109110
catch (SqlException e)
110111
{
111112
retryParamenter.Exception = e;
112-
if (!canRetry(retryParamenter))
113+
if (!(await canRetry(retryParamenter)))
113114
{
114115
throw;
115116
}
116117
}
117118
}
118119
}
119120

121+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
120122
public static bool IsFatalSqlException(SqlException ex)
121123
{
122124
// We will retry sql operations for serious errors.

0 commit comments

Comments
 (0)