如何减少通用缓存存储库中读者的锁定?

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 作为静态变量,您的代码就可以正常工作。