动态信号量请求计数

时间:2018-07-02 07:27:19

标签: c# multithreading asp.net-web-api semaphore

我有一个ASP.NET应用程序,该应用程序使用仅用于进行一次API调用的缓存。

此刻,如果我收到多个请求,它们最终都会命中API,而不是读取缓存,因为请求返回需要一段时间。如此有效地导致了我的缓存丢失,因此为了防止这种情况,我这样做了:

user_package

这可以通过在一个请求获得锁后立即阻止每个请求来进行工作,但是,就像互斥锁一样,它将允许一个接一个地访问缓存...

所以理想的行为是,每个请求都由select u.*, p.name from packages p left join user_package u on u.pid = p.id and u.uid=1 保留,然后第一个请求实际解决了API请求后,就让每个请求继续(因为它们都将进入缓存)。

我认为将class GetData { private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim( 1, 1 ); public async Task<ReferenceDataModel> GetReferenceDataAsync() { this.logger.Trace( "About to hit Reference Data lock" ); await SemaphoreSlim.WaitAsync( ); this.logger.Trace( "Acquired Thread" ); var referenceDataModel = await this.GetReferenceDataImplAsync(); this.logger.Trace( "Releasing Thread" ); SemaphoreSlim.Release( 1 ); return referenceDataModel; } private async Task<ReferenceDataModel> GetReferenceDataImplAsync() { if ( this.cache.Contains( ReferenceDataCacheKey ) ) { this.logger.Trace( "Returning Cached Response" ); return (ReferenceDataModel) this.cache.Get( ReferenceDataCacheKey ); } this.logger.Trace( "Making Reference Data API call" ); var response = await this.referenceDataProvider.GetReferenceDataAsync().ConfigureAwait( false ); this.AddReferenceDataToCache( response ); return response; } private void AddReferenceDataToCache(ReferenceDataModel mappedResponse) { var currentDateTime = DateTime.UtcNow; var expirationOffset = currentDateTime.TimeOfDay < this.cacheExpiryTime ? currentDateTime.Date.Add(this.cacheExpiryTime) : currentDateTime.AddDays(1).Date.Add(this.cacheExpiryTime); this.cache.Set(ReferenceDataCacheKey, mappedResponse, expirationOffset); this.logger.Trace( "Cached API Call Response" ); } } WaitAsync()一起使用可能会起作用,其想法是取消所有等待,以便所有线程继续运行。

0 个答案:

没有答案