361*_*615 0 c# web-services locking async-await memorycache
我写了一个方法,应该从Web服务获取一些信息.我想避免额外调用该服务,所以我试图根据这篇文章将信息放入MemoryCache .
不同之处在于我在客户端没有"SomeHeavyAndExpensiveCalculation",但我将工作委托给了Web服务.所以我想等待电话.
据我了解当前的实现,我可能有多个请求到Web服务器,因为我无法等待锁内的请求,这就是为什么它被移出锁.
有更好的解决方案吗?
谢谢.
private static readonly object CompanyInfoLock = new object();
public async Task<CompanyDto> GetCompanyInfo()
{
const string cacheKey = "_COMPANYINFO_";
CompanyDto companyInfo = MemoryCache.Default[cacheKey] as CompanyDto;
if (companyInfo != null) return companyInfo;
CompanyDto company = await _userManagementService.InvokeAsync(x => x.GetCompanyAsync(AppPrincipal.Current.CurrentCompanyId));
lock (CompanyInfoLock)
{
companyInfo = MemoryCache.Default[cacheKey] as CompanyDto;
if (companyInfo != null) return companyInfo;
MemoryCache.Default.Add(cacheKey, company, new CacheItemPolicy
{
SlidingExpiration = new TimeSpan(2, 0, 0)
});
}
return company;
}
Run Code Online (Sandbox Code Playgroud)
使用a SemaphoreSlim可以在调用Web服务之前异步锁定并放置锁定块.
private static readonly SemaphoreSlim CompanyInfoLock = new SemaphoreSlim (1);
public async Task<CompanyDto> GetCompanyInfo()
{
const string cacheKey = "_COMPANYINFO_";
CompanyDto companyInfo;
companyInfo = MemoryCache.Default[cacheKey] as CompanyDto;
if (companyInfo != null) return companyInfo;
await CompanyInfoLock.WaitAsync();
try
{
//Check a 2nd time inside the lock to see if the cache has the data.
companyInfo = MemoryCache.Default[cacheKey] as CompanyDto;
if (companyInfo != null) return companyInfo;
companyInfo = await _userManagementService.InvokeAsync(x => x.GetCompanyAsync(AppPrincipal.Current.CurrentCompanyId));
MemoryCache.Default.Add(cacheKey, companyInfo, new CacheItemPolicy
{
SlidingExpiration = new TimeSpan(2, 0, 0)
});
return companyInfo;
}
finally
{
CompanyInfoLock.Release();
}
}
Run Code Online (Sandbox Code Playgroud)