Skip to main content
 首页 » 编程设计

c#之Asp.net 核心 DI : Using SemaphoreSlim for write AND read operations with Singleton

2024年02月25日36lonelyxmas

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

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

这是我正在做的事情的配对草图:

namespace MyApp.Global 
{ 
 
    public interface IMyGlobalDataService 
    { 
        Task<List<ImportantDataItem>> GetFilteredDataOfMyList(string prop1); 
        Task LoadMyImportantDataListAsync(); 
    } 
 
    public class MyGlobalDataService: IMyGlobalDataService 
    { 
        private MyDbContext _myDbContext; 
 
        private readonly SemaphoreSlim myImportantDataLock = new SemaphoreSlim(1, 1); 
        private List<ImportantDataItem> myImportantDataList { get; set; } 
        public async Task<List<ImportantDataItem>> GetFilteredDataOfMyList(string prop1) 
        { 
            List<ImportantDataItem> list; 
            myImportantDataLock.WaitAsync(); 
            try 
            { 
                list = myImportantDataList.Where(itm => itm.Prop1 == prop1).ToList(); 
            } 
            finally 
            { 
                myImportantDataLock.Release(); 
            } 
            return list; 
        } 
 
        public async Task LoadMyImportantDataListAsync() 
        { 
            // this method gets called when the Service is created and once every hour thereafter 
 
            myImportantDataLock.WaitAsync(); 
            try 
            { 
                this.MyImportantDataList = await _myDbContext.ImportantDataItems.ToListAsync(); 
            } 
            finally 
            { 
                myImportantDataLock.Release(); 
            } 
            return; 
        } 
 
 
        public MyGlobalDataService(MyDbContext myDbContext) { 
            _myDbContext = myDbContext; 
        }; 
    } 
}

所以实际上,我使用 SemaphoreSlim 来限制一次一个线程的访问,用于对 myImportantDataList 的读取和更新。这对我来说真的是一个不确定的领域。这似乎是处理我在整个应用程序中注入(inject)全局数据单例的合适方法吗?或者我应该期待疯狂的线程锁定/阻塞?

请您参考如下方法:

使用 SemaphoreSlim 的问题是可扩展性。

因为这是在 Web 应用程序中,可以公平地假设您希望有可能让多个读者同时访问数据。但是,您(可以理解)将可以同时生成的信号量请求数限制为 1(以防止并发读取和写入请求)。这意味着您也将序列化所有读取。

你需要使用类似 ReaderWriterLockSlim 的东西允许多个线程读取,但确保独占写入。