首页 > 解决方案 > 如何在 C# UWP 应用程序中实现自定义缓存

问题描述

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

要求是:

标签: c#asp.netcachinguwp

解决方案


为满足上述需求,在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 应用程序的设备请求产品列表时,该服务将检查该设备上的缓存是否存在且未过期,并在必要时调用服务器刷新缓存。


推荐阅读