如何减少通用缓存存储库中读者的锁定?
How can I reduce locking for readers in generic cached repository?
我创建了一个通用的 CachedRepository
,如下所示:
public class CachedRepository<T> : ICachedRepository, IRepository<T> where T : BaseModel, new()
{
private static readonly Lock<T> TypeLock = new Lock<T>();
public void DeleteBatch(IQueryable<T> entities)
{
lock (TypeLock)
{
// delete logic here
}
}
public T GetNoTracking(int id)
{
lock (TypeLock)
{
// fetch by id logic here
}
}
}
通过使用通用对象进行锁定,我将获得每种类型的锁定(即处理不同类型的线程不会一个接一个地等待)。但是,此 class 用于很少更改但被大量读取的对象列表,因此使用 lock
的简单锁定将延迟 reader 直到另一个 reader 完成.
我查看了 ReaderWriterLockSlim,但它不是通用的 class,如果我使用它,我将失去我现在拥有的类型锁定。
问题: 如何在保持 lock(generic_type_instance)
模式提供的类型锁定的同时减少 reader 的锁定?
注意: @Servy 完全正确。示例中的这种抽象只是您场景的开销。
您可以将 ReaderWriterLockSlim 包装成通用 class。暴露ReaderWriterLockSlim读写锁的Enter、Exit方法,才能正确使用
只是一个示例:
internal class ReaderFreadlyLock<T>
{
private readonly ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
public T Read(Func<T> func)
{
this.lck.EnterReadLock();
try
{
return func();
}
finally
{
this.lck.ExitReadLock();
}
}
public void Write(Action action)
{
this.lck.EnterReadLock();
try
{
action();
}
finally
{
this.lck.ExitWriteLock();
}
}
}
那么你可以这样使用它:
var chached = TypeLock.Read(() => {
// read from cache
});
TypeLock.Write(() => {
// write to db
// write to cache
});
锁不需要是通用的。该对象所在的class是泛型的,所以对于CachedRepository
的每个泛型类型输入已经有不同的静态变量,不管静态对象是否也是泛型。只需使用常规 ReaderWriterLockSlim
作为静态变量,您的代码就可以正常工作。
我创建了一个通用的 CachedRepository
,如下所示:
public class CachedRepository<T> : ICachedRepository, IRepository<T> where T : BaseModel, new()
{
private static readonly Lock<T> TypeLock = new Lock<T>();
public void DeleteBatch(IQueryable<T> entities)
{
lock (TypeLock)
{
// delete logic here
}
}
public T GetNoTracking(int id)
{
lock (TypeLock)
{
// fetch by id logic here
}
}
}
通过使用通用对象进行锁定,我将获得每种类型的锁定(即处理不同类型的线程不会一个接一个地等待)。但是,此 class 用于很少更改但被大量读取的对象列表,因此使用 lock
的简单锁定将延迟 reader 直到另一个 reader 完成.
我查看了 ReaderWriterLockSlim,但它不是通用的 class,如果我使用它,我将失去我现在拥有的类型锁定。
问题: 如何在保持 lock(generic_type_instance)
模式提供的类型锁定的同时减少 reader 的锁定?
注意: @Servy 完全正确。示例中的这种抽象只是您场景的开销。
您可以将 ReaderWriterLockSlim 包装成通用 class。暴露ReaderWriterLockSlim读写锁的Enter、Exit方法,才能正确使用
只是一个示例:
internal class ReaderFreadlyLock<T>
{
private readonly ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
public T Read(Func<T> func)
{
this.lck.EnterReadLock();
try
{
return func();
}
finally
{
this.lck.ExitReadLock();
}
}
public void Write(Action action)
{
this.lck.EnterReadLock();
try
{
action();
}
finally
{
this.lck.ExitWriteLock();
}
}
}
那么你可以这样使用它:
var chached = TypeLock.Read(() => {
// read from cache
});
TypeLock.Write(() => {
// write to db
// write to cache
});
锁不需要是通用的。该对象所在的class是泛型的,所以对于CachedRepository
的每个泛型类型输入已经有不同的静态变量,不管静态对象是否也是泛型。只需使用常规 ReaderWriterLockSlim
作为静态变量,您的代码就可以正常工作。