C# Asp.net核心DI:使用信号量LIM进行单例写和读操作

C# Asp.net核心DI:使用信号量LIM进行单例写和读操作,c#,dependency-injection,singleton,semaphore,asp.net-core-2.2,C#,Dependency Injection,Singleton,Semaphore,Asp.net Core 2.2,我正在重新加工ASP.NET CORE 2.2应用程序,以避免将服务定位器模式与静态类结合使用。双重坏 重新工具化涉及到创建和注入Singleton对象作为一些全局数据的存储库。这里的想法是为了避免在请求中反复使用的一些基本/全局数据被我的SQL server命中。但是,这些数据需要每小时更新一次(不仅仅是在应用程序启动时)。因此,为了管理这种情况,我使用SemaphoreSlim处理对数据对象的一次性访问 下面是我正在做的一对草图: 名称空间MyApp.Global { 公共接口IMyGlo

我正在重新加工ASP.NET CORE 2.2应用程序,以避免将服务定位器模式与静态类结合使用。双重坏

重新工具化涉及到创建和注入Singleton对象作为一些全局数据的存储库。这里的想法是为了避免在请求中反复使用的一些基本/全局数据被我的SQL server命中。但是,这些数据需要每小时更新一次(不仅仅是在应用程序启动时)。因此,为了管理这种情况,我使用SemaphoreSlim处理对数据对象的一次性访问

下面是我正在做的一对草图:

名称空间MyApp.Global
{
公共接口IMyGlobalDataService
{
任务GetFilteredDataOfMyList(字符串prop1);
任务LoadMyImportantDataListSync();
}
公共类MyGlobalDataService:IMyGlobalDataService
{
私有mydbcontextu MyDbContext;
私有只读信号量lim myImportantDataLock=新信号量lim(1,1);
私有列表myImportantDataList{get;set;}
公共异步任务GetFilteredDataOfMyList(字符串prop1)
{
名单;
myImportantDataLock.WaitAsync();
尝试
{
list=myImportantDataList.Where(itm=>itm.Prop1==Prop1.ToList();
}
最后
{
myImportantDataLock.Release();
}
退货清单;
}
公共异步任务LoadMyImportantDataListSync()
{
//此方法在创建服务时调用,此后每小时调用一次
myImportantDataLock.WaitAsync();
尝试
{
this.MyImportantDataList=wait_myDbContext.ImportantDataItems.toListSync();
}
最后
{
myImportantDataLock.Release();
}
返回;
}
公共MyGlobalDataService(MyDbContext MyDbContext){
_myDbContext=myDbContext;
};
}

}
使用
信号量LIM的问题在于可伸缩性

由于这是在web应用程序中进行的,因此可以公平地假设您希望有多个读卡器同时访问数据的潜力。但是,您(可以理解)将可并发生成的信号量请求数量限制为1(以防止并发读写请求)。这意味着您也将序列化所有读取


您需要使用类似的方法来允许多线程阅读,但要确保以独占方式进行书写。

Creyke的回答对我来说一针见血:使用ReaderWriterLockSlim。因此,我将其标记为已接受的答案。但我正在发布我修改过的解决方案,以防对任何人都有帮助。需要注意的是,我使用以下软件包为ReaderWriterLockSlim提供异步功能:

使用Nito.AsyncEx;
使用制度;
使用System.Collections.Generic;
使用系统文本;
名称空间MyApp.Global
{
公共接口IMyGlobalDataService
{
任务GetFilteredDataOfMyList(字符串prop1);
任务LoadMyImportantDataListSync();
}
公共类MyGlobalDataService:IMyGlobalDataService
{
私有mydbcontextu MyDbContext;
私有只读AsyncReaderWriterLock myImportantDataLock=new AsyncReaderWriterLock();
私有列表myImportantDataList{get;set;}
公共异步任务GetFilteredDataOfMyList(字符串prop1)
{
名单;
使用(等待myImportantDataLock.ReaderLockAsync())
{
list=myImportantDataList.Where(itm=>itm.Prop1==Prop1.ToList();
}
退货清单;
}
公共异步任务LoadMyImportantDataListSync()
{
//此方法在创建服务时调用,此后每小时调用一次
使用(等待myImportantDataLock.WriterLockAsync())
{
this.MyImportantDataList=wait_myDbContext.ImportantDataItems.toListSync();
}
返回;
}
公共MyGlobalDataService(MyDbContext MyDbContext)
{
_myDbContext=myDbContext;
};
}

}
是的,你说出了我的直觉给我的建议。非常感谢您的反馈!将检查ReaderWriterLockSlim上的链接