Add cancellation token support

This commit is contained in:
John Luo 2017-05-22 02:12:25 -07:00
Родитель 607878d77f
Коммит eae4e40bc2
13 изменённых файлов: 233 добавлений и 62 удалений

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.Extensions.Caching.Distributed namespace Microsoft.Extensions.Caching.Distributed
@ -9,18 +10,18 @@ namespace Microsoft.Extensions.Caching.Distributed
{ {
byte[] Get(string key); byte[] Get(string key);
Task<byte[]> GetAsync(string key); Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken));
void Set(string key, byte[] value, DistributedCacheEntryOptions options); void Set(string key, byte[] value, DistributedCacheEntryOptions options);
Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options); Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken));
void Refresh(string key); void Refresh(string key);
Task RefreshAsync(string key); Task RefreshAsync(string key, CancellationToken token = default(CancellationToken));
void Remove(string key); void Remove(string key);
Task RemoveAsync(string key); Task RemoveAsync(string key, CancellationToken token = default(CancellationToken));
} }
} }

Просмотреть файл

@ -0,0 +1,42 @@
[
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task RefreshAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task RemoveAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options)",
"Kind": "Removal"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task RefreshAsync(System.String key, System.Threading.CancellationToken token = default(System.Threading.CancellationToken))",
"Kind": "Addition"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task RemoveAsync(System.String key, System.Threading.CancellationToken token = default(System.Threading.CancellationToken))",
"Kind": "Addition"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options, System.Threading.CancellationToken token = default(System.Threading.CancellationToken))",
"Kind": "Addition"
},
{
"TypeId": "public interface Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key, System.Threading.CancellationToken token = default(System.Threading.CancellationToken))",
"Kind": "Addition"
}
]

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
@ -33,7 +34,7 @@ namespace Microsoft.Extensions.Caching.Distributed
return (byte[])_memCache.Get(key); return (byte[])_memCache.Get(key);
} }
public Task<byte[]> GetAsync(string key) public Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
@ -68,7 +69,7 @@ namespace Microsoft.Extensions.Caching.Distributed
_memCache.Set(key, value, memoryCacheEntryOptions); _memCache.Set(key, value, memoryCacheEntryOptions);
} }
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options) public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
@ -100,7 +101,7 @@ namespace Microsoft.Extensions.Caching.Distributed
_memCache.TryGetValue(key, out value); _memCache.TryGetValue(key, out value);
} }
public Task RefreshAsync(string key) public Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
@ -121,7 +122,7 @@ namespace Microsoft.Extensions.Caching.Distributed
_memCache.Remove(key); _memCache.Remove(key);
} }
public Task RemoveAsync(string key) public Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {

Просмотреть файл

@ -8,5 +8,25 @@
"TypeId": "public class Microsoft.Extensions.Caching.Memory.MemoryCacheOptions : Microsoft.Extensions.Options.IOptions<Microsoft.Extensions.Caching.Memory.MemoryCacheOptions>", "TypeId": "public class Microsoft.Extensions.Caching.Memory.MemoryCacheOptions : Microsoft.Extensions.Options.IOptions<Microsoft.Extensions.Caching.Memory.MemoryCacheOptions>",
"MemberId": "public System.Void set_CompactOnMemoryPressure(System.Boolean value)", "MemberId": "public System.Void set_CompactOnMemoryPressure(System.Boolean value)",
"Kind": "Removal" "Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task RefreshAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task RemoveAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key)",
"Kind": "Removal"
} }
] ]

Просмотреть файл

@ -8,5 +8,25 @@
"TypeId": "public class Microsoft.Extensions.Caching.Memory.MemoryCacheOptions : Microsoft.Extensions.Options.IOptions<Microsoft.Extensions.Caching.Memory.MemoryCacheOptions>", "TypeId": "public class Microsoft.Extensions.Caching.Memory.MemoryCacheOptions : Microsoft.Extensions.Options.IOptions<Microsoft.Extensions.Caching.Memory.MemoryCacheOptions>",
"MemberId": "public System.Void set_CompactOnMemoryPressure(System.Boolean value)", "MemberId": "public System.Void set_CompactOnMemoryPressure(System.Boolean value)",
"Kind": "Removal" "Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task RefreshAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task RemoveAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache",
"MemberId": "public System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key)",
"Kind": "Removal"
} }
] ]

Просмотреть файл

@ -60,14 +60,16 @@ namespace Microsoft.Extensions.Caching.Redis
return GetAndRefresh(key, getData: true); return GetAndRefresh(key, getData: true);
} }
public async Task<byte[]> GetAsync(string key) public async Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
return await GetAndRefreshAsync(key, getData: true); token.ThrowIfCancellationRequested();
return await GetAndRefreshAsync(key, getData: true, token: token);
} }
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
@ -103,7 +105,7 @@ namespace Microsoft.Extensions.Caching.Redis
}); });
} }
public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options) public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
@ -120,7 +122,9 @@ namespace Microsoft.Extensions.Caching.Redis
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
await ConnectAsync(); token.ThrowIfCancellationRequested();
await ConnectAsync(token);
var creationTime = DateTimeOffset.UtcNow; var creationTime = DateTimeOffset.UtcNow;
@ -146,14 +150,16 @@ namespace Microsoft.Extensions.Caching.Redis
GetAndRefresh(key, getData: false); GetAndRefresh(key, getData: false);
} }
public async Task RefreshAsync(string key) public async Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
await GetAndRefreshAsync(key, getData: false); token.ThrowIfCancellationRequested();
await GetAndRefreshAsync(key, getData: false, token: token);
} }
private void Connect() private void Connect()
@ -178,8 +184,10 @@ namespace Microsoft.Extensions.Caching.Redis
} }
} }
private async Task ConnectAsync() private async Task ConnectAsync(CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
if (_connection != null) if (_connection != null)
{ {
return; return;
@ -240,14 +248,16 @@ namespace Microsoft.Extensions.Caching.Redis
return null; return null;
} }
private async Task<byte[]> GetAndRefreshAsync(string key, bool getData) private async Task<byte[]> GetAndRefreshAsync(string key, bool getData, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
await ConnectAsync(); token.ThrowIfCancellationRequested();
await ConnectAsync(token);
// This also resets the LRU status as desired. // This also resets the LRU status as desired.
// TODO: Can this be done in one operation on the server side? Probably, the trick would just be the DateTimeOffset math. // TODO: Can this be done in one operation on the server side? Probably, the trick would just be the DateTimeOffset math.
@ -269,7 +279,7 @@ namespace Microsoft.Extensions.Caching.Redis
DateTimeOffset? absExpr; DateTimeOffset? absExpr;
TimeSpan? sldExpr; TimeSpan? sldExpr;
MapMetadata(results, out absExpr, out sldExpr); MapMetadata(results, out absExpr, out sldExpr);
await RefreshAsync(key, absExpr, sldExpr); await RefreshAsync(key, absExpr, sldExpr, token);
} }
if (results.Length >= 3 && results[2].HasValue) if (results.Length >= 3 && results[2].HasValue)
@ -293,14 +303,14 @@ namespace Microsoft.Extensions.Caching.Redis
// TODO: Error handling // TODO: Error handling
} }
public async Task RemoveAsync(string key) public async Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
await ConnectAsync(); await ConnectAsync(token);
await _cache.KeyDeleteAsync(_instance + key); await _cache.KeyDeleteAsync(_instance + key);
// TODO: Error handling // TODO: Error handling
@ -347,13 +357,15 @@ namespace Microsoft.Extensions.Caching.Redis
} }
} }
private async Task RefreshAsync(string key, DateTimeOffset? absExpr, TimeSpan? sldExpr) private async Task RefreshAsync(string key, DateTimeOffset? absExpr, TimeSpan? sldExpr, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
token.ThrowIfCancellationRequested();
// Note Refresh has no effect if there is just an absolute expiration (or neither). // Note Refresh has no effect if there is just an absolute expiration (or neither).
TimeSpan? expr = null; TimeSpan? expr = null;
if (sldExpr.HasValue) if (sldExpr.HasValue)

Просмотреть файл

@ -0,0 +1,22 @@
[
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task RefreshAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task RemoveAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key)",
"Kind": "Removal"
}
]

Просмотреть файл

@ -0,0 +1,22 @@
[
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task RefreshAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task RemoveAsync(System.String key)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task SetAsync(System.String key, System.Byte[] value, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions options)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.Extensions.Caching.Redis.RedisCache : Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.IDisposable",
"MemberId": "public System.Threading.Tasks.Task<System.Byte[]> GetAsync(System.String key)",
"Kind": "Removal"
}
]

Просмотреть файл

@ -8,6 +8,7 @@ using System.Data.SqlClient;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
using System.Threading;
namespace Microsoft.Extensions.Caching.SqlServer namespace Microsoft.Extensions.Caching.SqlServer
{ {
@ -61,16 +62,18 @@ namespace Microsoft.Extensions.Caching.SqlServer
} }
} }
public async Task DeleteCacheItemAsync(string key) public async Task DeleteCacheItemAsync(string key, CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
using (var connection = new SqlConnection(ConnectionString)) using (var connection = new SqlConnection(ConnectionString))
{ {
var command = new SqlCommand(SqlQueries.DeleteCacheItem, connection); var command = new SqlCommand(SqlQueries.DeleteCacheItem, connection);
command.Parameters.AddCacheItemId(key); command.Parameters.AddCacheItemId(key);
await connection.OpenAsync(); await connection.OpenAsync(token);
await command.ExecuteNonQueryAsync(); await command.ExecuteNonQueryAsync(token);
} }
} }
@ -79,9 +82,11 @@ namespace Microsoft.Extensions.Caching.SqlServer
return GetCacheItem(key, includeValue: true); return GetCacheItem(key, includeValue: true);
} }
public virtual async Task<byte[]> GetCacheItemAsync(string key) public virtual async Task<byte[]> GetCacheItemAsync(string key, CancellationToken token = default(CancellationToken))
{ {
return await GetCacheItemAsync(key, includeValue: true); token.ThrowIfCancellationRequested();
return await GetCacheItemAsync(key, includeValue: true, token: token);
} }
public void RefreshCacheItem(string key) public void RefreshCacheItem(string key)
@ -89,9 +94,11 @@ namespace Microsoft.Extensions.Caching.SqlServer
GetCacheItem(key, includeValue: false); GetCacheItem(key, includeValue: false);
} }
public async Task RefreshCacheItemAsync(string key) public async Task RefreshCacheItemAsync(string key, CancellationToken token = default(CancellationToken))
{ {
await GetCacheItemAsync(key, includeValue: false); token.ThrowIfCancellationRequested();
await GetCacheItemAsync(key, includeValue: false, token:token);
} }
public virtual void DeleteExpiredCacheItems() public virtual void DeleteExpiredCacheItems()
@ -147,8 +154,10 @@ namespace Microsoft.Extensions.Caching.SqlServer
} }
} }
public virtual async Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options) public virtual async Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
var utcNow = SystemClock.UtcNow; var utcNow = SystemClock.UtcNow;
var absoluteExpiration = GetAbsoluteExpiration(utcNow, options); var absoluteExpiration = GetAbsoluteExpiration(utcNow, options);
@ -164,11 +173,11 @@ namespace Microsoft.Extensions.Caching.SqlServer
.AddAbsoluteExpiration(absoluteExpiration) .AddAbsoluteExpiration(absoluteExpiration)
.AddWithValue("UtcNow", SqlDbType.DateTimeOffset, utcNow); .AddWithValue("UtcNow", SqlDbType.DateTimeOffset, utcNow);
await connection.OpenAsync(); await connection.OpenAsync(token);
try try
{ {
await upsertCommand.ExecuteNonQueryAsync(); await upsertCommand.ExecuteNonQueryAsync(token);
} }
catch (SqlException ex) catch (SqlException ex)
{ {
@ -247,8 +256,10 @@ namespace Microsoft.Extensions.Caching.SqlServer
return value; return value;
} }
protected virtual async Task<byte[]> GetCacheItemAsync(string key, bool includeValue) protected virtual async Task<byte[]> GetCacheItemAsync(string key, bool includeValue, CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
var utcNow = SystemClock.UtcNow; var utcNow = SystemClock.UtcNow;
string query; string query;
@ -272,33 +283,35 @@ namespace Microsoft.Extensions.Caching.SqlServer
.AddCacheItemId(key) .AddCacheItemId(key)
.AddWithValue("UtcNow", SqlDbType.DateTimeOffset, utcNow); .AddWithValue("UtcNow", SqlDbType.DateTimeOffset, utcNow);
await connection.OpenAsync(); await connection.OpenAsync(token);
var reader = await command.ExecuteReaderAsync( var reader = await command.ExecuteReaderAsync(
CommandBehavior.SequentialAccess | CommandBehavior.SingleRow | CommandBehavior.SingleResult); CommandBehavior.SequentialAccess | CommandBehavior.SingleRow | CommandBehavior.SingleResult,
token);
if (await reader.ReadAsync()) if (await reader.ReadAsync(token))
{ {
var id = await reader.GetFieldValueAsync<string>(Columns.Indexes.CacheItemIdIndex); var id = await reader.GetFieldValueAsync<string>(Columns.Indexes.CacheItemIdIndex, token);
expirationTime = await reader.GetFieldValueAsync<DateTimeOffset>( expirationTime = await reader.GetFieldValueAsync<DateTimeOffset>(
Columns.Indexes.ExpiresAtTimeIndex); Columns.Indexes.ExpiresAtTimeIndex);
if (!await reader.IsDBNullAsync(Columns.Indexes.SlidingExpirationInSecondsIndex)) if (!await reader.IsDBNullAsync(Columns.Indexes.SlidingExpirationInSecondsIndex, token))
{ {
slidingExpiration = TimeSpan.FromSeconds( slidingExpiration = TimeSpan.FromSeconds(
await reader.GetFieldValueAsync<long>(Columns.Indexes.SlidingExpirationInSecondsIndex)); await reader.GetFieldValueAsync<long>(Columns.Indexes.SlidingExpirationInSecondsIndex, token));
} }
if (!await reader.IsDBNullAsync(Columns.Indexes.AbsoluteExpirationIndex)) if (!await reader.IsDBNullAsync(Columns.Indexes.AbsoluteExpirationIndex, token))
{ {
absoluteExpiration = await reader.GetFieldValueAsync<DateTimeOffset>( absoluteExpiration = await reader.GetFieldValueAsync<DateTimeOffset>(
Columns.Indexes.AbsoluteExpirationIndex); Columns.Indexes.AbsoluteExpirationIndex,
token);
} }
if (includeValue) if (includeValue)
{ {
value = await reader.GetFieldValueAsync<byte[]>(Columns.Indexes.CacheItemValueIndex); value = await reader.GetFieldValueAsync<byte[]>(Columns.Indexes.CacheItemValueIndex, token);
} }
} }
else else

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
@ -10,19 +11,19 @@ namespace Microsoft.Extensions.Caching.SqlServer
{ {
byte[] GetCacheItem(string key); byte[] GetCacheItem(string key);
Task<byte[]> GetCacheItemAsync(string key); Task<byte[]> GetCacheItemAsync(string key, CancellationToken token = default(CancellationToken));
void RefreshCacheItem(string key); void RefreshCacheItem(string key);
Task RefreshCacheItemAsync(string key); Task RefreshCacheItemAsync(string key, CancellationToken token = default(CancellationToken));
void DeleteCacheItem(string key); void DeleteCacheItem(string key);
Task DeleteCacheItemAsync(string key); Task DeleteCacheItemAsync(string key, CancellationToken token = default(CancellationToken));
void SetCacheItem(string key, byte[] value, DistributedCacheEntryOptions options); void SetCacheItem(string key, byte[] value, DistributedCacheEntryOptions options);
Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options); Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken));
void DeleteExpiredCacheItems(); void DeleteExpiredCacheItems();
} }

Просмотреть файл

@ -4,6 +4,7 @@
using System; using System;
using System.Data; using System.Data;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
@ -79,8 +80,10 @@ namespace Microsoft.Extensions.Caching.SqlServer
return value; return value;
} }
protected override async Task<byte[]> GetCacheItemAsync(string key, bool includeValue) protected override async Task<byte[]> GetCacheItemAsync(string key, bool includeValue, CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
var utcNow = SystemClock.UtcNow; var utcNow = SystemClock.UtcNow;
string query; string query;
@ -104,24 +107,25 @@ namespace Microsoft.Extensions.Caching.SqlServer
.AddCacheItemId(key) .AddCacheItemId(key)
.AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime); .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
await connection.OpenAsync(); await connection.OpenAsync(token);
var reader = await command.ExecuteReaderAsync( var reader = await command.ExecuteReaderAsync(
CommandBehavior.SingleRow | CommandBehavior.SingleResult); CommandBehavior.SingleRow | CommandBehavior.SingleResult,
token);
if (await reader.ReadAsync()) if (await reader.ReadAsync(token))
{ {
var id = reader.GetString(Columns.Indexes.CacheItemIdIndex); var id = reader.GetString(Columns.Indexes.CacheItemIdIndex);
expirationTime = DateTimeOffset.Parse(reader[Columns.Indexes.ExpiresAtTimeIndex].ToString()); expirationTime = DateTimeOffset.Parse(reader[Columns.Indexes.ExpiresAtTimeIndex].ToString());
if (!await reader.IsDBNullAsync(Columns.Indexes.SlidingExpirationInSecondsIndex)) if (!await reader.IsDBNullAsync(Columns.Indexes.SlidingExpirationInSecondsIndex, token))
{ {
slidingExpiration = TimeSpan.FromSeconds( slidingExpiration = TimeSpan.FromSeconds(
Convert.ToInt64(reader[Columns.Indexes.SlidingExpirationInSecondsIndex].ToString())); Convert.ToInt64(reader[Columns.Indexes.SlidingExpirationInSecondsIndex].ToString()));
} }
if (!await reader.IsDBNullAsync(Columns.Indexes.AbsoluteExpirationIndex)) if (!await reader.IsDBNullAsync(Columns.Indexes.AbsoluteExpirationIndex, token))
{ {
absoluteExpiration = DateTimeOffset.Parse( absoluteExpiration = DateTimeOffset.Parse(
reader[Columns.Indexes.AbsoluteExpirationIndex].ToString()); reader[Columns.Indexes.AbsoluteExpirationIndex].ToString());
@ -179,8 +183,10 @@ namespace Microsoft.Extensions.Caching.SqlServer
} }
} }
public override async Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options) public override async Task SetCacheItemAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{ {
token.ThrowIfCancellationRequested();
var utcNow = SystemClock.UtcNow; var utcNow = SystemClock.UtcNow;
var absoluteExpiration = GetAbsoluteExpiration(utcNow, options); var absoluteExpiration = GetAbsoluteExpiration(utcNow, options);
@ -196,11 +202,11 @@ namespace Microsoft.Extensions.Caching.SqlServer
.AddAbsoluteExpirationMono(absoluteExpiration) .AddAbsoluteExpirationMono(absoluteExpiration)
.AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime); .AddWithValue("UtcNow", SqlDbType.DateTime, utcNow.UtcDateTime);
await connection.OpenAsync(); await connection.OpenAsync(token);
try try
{ {
await upsertCommand.ExecuteNonQueryAsync(); await upsertCommand.ExecuteNonQueryAsync(token);
} }
catch (SqlException ex) catch (SqlException ex)
{ {

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
@ -99,13 +100,15 @@ namespace Microsoft.Extensions.Caching.SqlServer
return value; return value;
} }
public async Task<byte[]> GetAsync(string key) public async Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
token.ThrowIfCancellationRequested();
var value = await _dbOperations.GetCacheItemAsync(key); var value = await _dbOperations.GetCacheItemAsync(key);
ScanForExpiredItemsIfRequired(); ScanForExpiredItemsIfRequired();
@ -125,13 +128,15 @@ namespace Microsoft.Extensions.Caching.SqlServer
ScanForExpiredItemsIfRequired(); ScanForExpiredItemsIfRequired();
} }
public async Task RefreshAsync(string key) public async Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
token.ThrowIfCancellationRequested();
await _dbOperations.RefreshCacheItemAsync(key); await _dbOperations.RefreshCacheItemAsync(key);
ScanForExpiredItemsIfRequired(); ScanForExpiredItemsIfRequired();
@ -149,13 +154,15 @@ namespace Microsoft.Extensions.Caching.SqlServer
ScanForExpiredItemsIfRequired(); ScanForExpiredItemsIfRequired();
} }
public async Task RemoveAsync(string key) public async Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
token.ThrowIfCancellationRequested();
await _dbOperations.DeleteCacheItemAsync(key); await _dbOperations.DeleteCacheItemAsync(key);
ScanForExpiredItemsIfRequired(); ScanForExpiredItemsIfRequired();
@ -188,7 +195,8 @@ namespace Microsoft.Extensions.Caching.SqlServer
public async Task SetAsync( public async Task SetAsync(
string key, string key,
byte[] value, byte[] value,
DistributedCacheEntryOptions options) DistributedCacheEntryOptions options,
CancellationToken token = default(CancellationToken))
{ {
if (key == null) if (key == null)
{ {
@ -205,6 +213,8 @@ namespace Microsoft.Extensions.Caching.SqlServer
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
token.ThrowIfCancellationRequested();
GetOptions(ref options); GetOptions(ref options);
await _dbOperations.SetCacheItemAsync(key, value, options); await _dbOperations.SetCacheItemAsync(key, value, options);

Просмотреть файл

@ -4,6 +4,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -143,7 +144,7 @@ namespace Microsoft.Extensions.Caching.Distributed
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task<byte[]> GetAsync(string key) public Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken))
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -153,7 +154,7 @@ namespace Microsoft.Extensions.Caching.Distributed
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task RefreshAsync(string key) public Task RefreshAsync(string key, CancellationToken token = default(CancellationToken))
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -163,7 +164,7 @@ namespace Microsoft.Extensions.Caching.Distributed
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task RemoveAsync(string key) public Task RemoveAsync(string key, CancellationToken token = default(CancellationToken))
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -173,7 +174,7 @@ namespace Microsoft.Extensions.Caching.Distributed
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options) public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }