我写了缓存更新功能。
以下是我的Redis Cache实现:
public class RedisCache : ICache
{
private readonly IDatabase _cache;
public RedisCache(string connectionString)
{
var connection = ConnectionMultiplexer.Connect(connectionString);
_cache = connection.GetDatabase();
}
public async Task<T> GetAsync<T>(string key)
{
var value = await _cache.StringGetAsync(key);
if (value.HasValue)
{
return JsonConvert.DeserializeObject<T>(value);
}
return default(T);
}
public async Task SetAsync<T>(string key, T value, TimeSpan ttl)
{
var serializedValue = JsonConvert.SerializeObject(value);
await _cache.StringSetAsync(key, serializedValue, ttl);
}
public T Get<T>(string key)
{
var value = _cache.StringGet(key);
if (value.HasValue)
{
return JsonConvert.DeserializeObject<T>(value);
}
return default(T);
}
public void Set<T>(string key, T value, TimeSpan ttl)
{
var serializedValue = JsonConvert.SerializeObject(value);
_cache.StringSet(key, serializedValue, ttl);
}
public async Task RemoveAsync(string key)
{
await _cache.KeyDeleteAsync(key);
}
}
在BackgroundService
中的用法:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var scope = _serviceProvider.CreateScope();
_cache = scope.ServiceProvider.GetService<ICache>();
_queue = scope.ServiceProvider.GetService<RefresBackgroundQueue>();
await foreach (string item in _queue.DequeueAllAsync(stoppingToken))
{
try
{
// some logic
await _cache.GetAsync<Model>(key)
// some logic
await _cache.SetAsync(randomKey, result, new TimeSpan(100, 0, 0, 0));
}
catch (Exception ex)
{
_logger.LogError($"Exception while updating cache: {ex.Message}, {ex.StackTrace}");
}
}
}
从上面的代码我得到uncatchable异常:
System.InvalidOperationException:读取器完成后不允许阅读。在System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed()在System.IO.Pipelines.Pipe.AdvanceReader(SequencePosition& consumed,SequencePosition& examined)在System.IO.Pipelines.Pipe.DefaultPipeReader.AdvanceTo(SequencePosition consumed,SequencePosition examined)在StackExchange.Redis.PhysicalConnection.ReadFromPipe()在/_/src/StackExchange.Redis/PhysicalConnection.cs:line 1729
在那种情况下我该怎么办?
1条答案
按热度按时间wsewodh21#
我在BackgroundService.cs中的ExecuteAsync中做了一些更改,
代码运行正常
ExecuteAsync
的更改
完整代码
在代码中,我使用了以下条件
while (!stoppingToken.IsCancellationRequested)
这是后台服务的主循环。只要取消令牌(stoppingToken
)没有被通知取消,它就继续执行。取消令牌通常用于在应用程序关闭时正常停止后台操作。await Task.Delay(1000, stoppingToken);
在循环内部,这行代码在循环迭代之间引入了1000毫秒(1秒)的延迟。await
关键字表示此操作是异步的,并允许其他任务在延迟发生时并发执行。