我需要在我的应用中使用IDistributedCache
,它可能是MemoryDistributedCache
或RedisCache
作为基础实现。我的理解不是线程安全的,因此我使用ReaderWriterLockSlim
创建了自己的包装器。
ReaderWriterLockSlim
允许多个线程用于读取,或互斥访问用于写入。现在,我想知道这是否是适合该工作的工具,并且MemoryDistributedCache
和RedisCache
读取方法是否是线程安全的。
关于整体解决方案-我知道从Redis等分布式缓存中存储和读取值需要花费时间。但是我没有太多选择,因为我存储的值更难获得和管理。
以下是代码段:
...
public async Task<byte[]> GetAsync(string key, CancellationToken token = new CancellationToken())
{
_cacheLock.EnterReadLock();
try
{
return await _cache.GetAsync(GetCacheKey(key), token);
}
finally
{
_cacheLock.ExitReadLock();
}
}
public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = new CancellationToken())
{
_cacheLock.EnterWriteLock();
try
{
await _cache.SetAsync(GetCacheKey(key), value, options, token);
}
finally
{
_cacheLock.ExitWriteLock();
}
}
public async Task RemoveAsync(string key, CancellationToken token = new CancellationToken())
{
_cacheLock.EnterWriteLock();
try
{
await _cache.RemoveAsync(GetCacheKey(key), token);
}
finally
{
_cacheLock.ExitWriteLock();
}
}
所有IDistributedCache
实现都应该是线程安全的。如果不是,请创建一个错误报告以修复它。
即使其中之一不是线程安全的,使用ReaderWriterLockSlim
保护async
代码也是无效的。从the docs:
ReaderWriterLockSlim具有托管线程相似性;也就是说,每个Thread对象必须进行自己的方法调用才能进入和退出锁定模式。没有线程可以更改另一个线程的模式。
最简单的解决方法是使用SemaphoreSlim
而不是ReaderWriterLockSlim
。