如何在C#UWP应用程序中实现自定义缓存

时间:2019-02-27 22:43:45

标签: c# asp.net caching uwp

我有一个Web服务( ItemWebService ),该服务调用API并获取项目列表( productList )。从 UWP应用程序调用该服务。

要求是:

  • 在特定时间段(例如1小时)内缓存产品列表,并在调用{{1时返回如果可用未超时 }}。
  • 无需每小时缓存,因为此过程将是非常罕见的过程,并且UWP应用程序在组织中的多个设备上运行。因此,如果将 interval 设置为要缓存,则该API将每小时每小时同时获取数百个请求。
  • 无论何时将方法<noscript> <style> {`.spinner { display: none !important; }`} </style> </noscript> 中的新商品添加到产品列表中,都应刷新缓存。

1 个答案:

答案 0 :(得分:0)

为了满足上述要求,在 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();
        }
    }
}

通过此实现,我能够避免设置时间间隔,这会导致数百次API调用(因为有数百台设备运行同一应用程序)每小时刷新一次缓存。

现在,每当运行UWP应用程序的设备请求产品列表时,该服务就会检查该设备上是否存在缓存且缓存未过期,并在必要时调用服务器刷新缓存。