使用 Rx 缓存来自 Web 服务的结果并在 C# UWP 应用程序中本地使用

Using Rx to cache result from webservice and use locally in C# UWP app

我有一个 UWP 应用程序,我在其中调用 Web 服务以从服务器获取产品列表。

ItemWebService

public async Task<IObservable<ProductListItem>> GetProductlistAsync()
{
     var productList = await _restClient.Get<IEnumerable<ProductListItem>>($"{_serviceUrl}/productlist");
     return productList.ToObservable();
}

ProductListItem class

public class ProductListItem
{
    public int Id { get; set; }
    public string SkuValue{ get; set; }
}

我想在特定时间段内缓存 productList(例如 10 分钟)。每当调用 GetProductlistAsync() 时,它应该首先查看缓存,如果存在缓存列表则 return。

我尝试在 ItemWebService 中保留一个局部变量来缓存列表。但是每当用户导航到另一个页面时,变量就会被清除。

注意:我将从我的 UWP 应用程序的不同页面调用此服务。因此,当用户导航到另一个页面时,代码不应清除缓存变量。

以下是我试过的代码。

private IObservable<ProductListItem> cachedProductList;

if (cachedProductList == null)
{
   var dbProductList = await GetProductlistAsync();
   var period = TimeSpan.FromSeconds(20);
   var observable = Observable.Interval(period).Publish();
   observable.Connect();
   observable.Subscribe(async l =>
                           {
                               cachedProductList = await 
                               GetProductlistAsync().ToObservable().Replay();
                           }
                        );
}

我想使用 Rx Extensions 实现此目的。

像这样简单的东西行得通吗?

private static IEnumerable<ProductListItem> _productList = null;
public async Task<IObservable<ProductListItem>> GetProductlistAsync()
{

    var productList = _productList;
    if (productList == null)
    {
        _productList = await _restClient.Get<IEnumerable<ProductListItem>>($"{_serviceUrl}/productlist");
        productList = _productList;
        Observable.Timer(TimeSpan.FromHours(1.0)).Subscribe(x => _productList = null);
    }
    return productList.ToObservable();
}

您正在寻找的是 ServiceCollection 依赖注入。你可以看看微软的这个sample application。一旦从 api 检索到服务,这对我在应用程序中持有服务的情况很有帮助。

其中您必须使用 AddSingleton 到 return 相同的对象。 AddTransient 将 return 不同的对象。 AddScoped 将 return 基于您调用的范围。