【问题标题】:How to implement customized cache in C# UWP application如何在 C# UWP 应用程序中实现自定义缓存
【发布时间】:2019-02-27 22:43:44
【问题描述】:

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

要求是:

  • 将产品列表缓存一段时间(例如:1 小时)并在调用GetProductListAsync() 时返回缓存列表如果可用未超时 .
  • 不需要每小时缓存一次,因为这个过程将是一个非常罕见的过程,而且 UWP 应用程序在组织中的多个设备上运行。因此,如果设置一个interval进行缓存,API每小时会同时收到数百个请求。
  • 每当从方法AddProductAsync(AddProductRequest addProductRequest ) 将新项目添加到产品列表时,都应刷新缓存。

【问题讨论】:

    标签: c# asp.net caching uwp


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2010-10-26
      • 2021-10-23
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多