我有一个Web服务( itemWebService ),该服务调用API并获取项目列表( productList )。此服务是从 UWP应用程序。
调用的要求是:
- 缓存一定时间段的产品列表(例如:1小时),然后返回缓存列表如果可用 and ,则称为
GetProductListAsync()
。/li>- 无需每个小时缓存,因为此过程将是一个非常罕见的过程,并且UWP应用程序是在组织中的多个设备上运行的。因此,如果将间隔设置为缓存,则API每小时会同时收到数百个请求。
- 每当将新项目从方法
AddProductAsync(AddProductRequest addProductRequest )
添加到产品列表中时,应刷新缓存。
为了满足上述要求,在 itemwebservice 中实现了自定义的缓存。
using NodaTime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Threading.Tasks;
namespace MyNamespace.Products
{
public class ItemWebService : IItemService
{
private readonly IApiRestClient _restClient;
private readonly string _serviceUrl = "api/products";
private static IEnumerable<ProductListItem> _cachedProductist = null;
private readonly IClock _clock;
private readonly Duration _productlistValidFor = Duration.FromHours(1); // Set the timeout
private static Instant _lastUpdate = Instant.MinValue;
public ItemWebService (IApiRestClient restClient)
{
_restClient = restClient;
_clock = SystemClock.Instance; // using NodaTime
}
public async Task AddProductAsync(AddProductRequest addProductRequest)
{
await _restClient.Put($"{_serviceUrl}/add", addProductRequest);
// Expire cache manually to update product list on next call
_lastUpdate = _clock.GetCurrentInstant() - _productlistValidFor ;
}
public async Task<IObservable<ProductListItem>> GetProductListAsync()
{
if (_cachedProductist == null || (_lastUpdate + _productlistValidFor) < _clock.GetCurrentInstant())
{
_cachedProductist = await _restClient.Get<IEnumerable<ProductListItem>>($"{_serviceUrl}/productList");
// Update the last updated time
_lastUpdate = _clock.GetCurrentInstant();
}
return _cachedProductist.ToObservable();
}
}
}
使用此实现,我能够避免设置 Interval ,该会导致数百个API调用(因为有数百个设备运行同一应用程序)每小时刷新缓存。
现在,每当运行UWP应用程序请求产品列表时,该服务都会检查缓存是否存在并且不在该设备上过期,并在必要时调用服务器以刷新缓存。