创建一个IObservable并立即返回缓存的异步操作的结果

时间:2010-12-08 10:39:15

标签: c# .net system.reactive

我正在使用反应式扩展来调用异步方法,我想缓存结果并将其返回给后续的方法调用。

如何创建Observable实例,返回它并提供订阅所需的数据(cacheResult)?

public IObservable<Bar> GetBars(int pageIndex, int pageSize)
{
   var @params = new object[] { pageIndex, pageSize };
   var cachedResult = _cache.Get(@params);
   if (cachedResult != null)
   {
 // How do I create a Observable instance and return the 'cacheResult'...
 return ...
   }

   var observable = new BaseObservable<Bar>();
   _components.WithSsoToken(_configuration.SsoToken)
      .Get(@params)
      .Select(Map)
      .Subscribe(c =>
                     {
                          _cache.Add(@params, c);
                          observable.Publish(c);
                          observable.Completed();
                     }, exception =>
                     {
                        observable.Failed(exception);
                        observable.Completed();
                     });

       return observable;
}

2 个答案:

答案 0 :(得分:3)

我相信您正在寻找Observable.Return

return Observable.Return((Bar)cachedResult);

一个不相关的说明:

  • 无需返回BaseObservable<T>。你应该返回一个Subject<T>,因为它执行的是你的实现,但它是线程安全的(你也应该在返回值上调用.AsObservable(),不能被强制转换)。
  • 您使用Do将值添加到缓存中:
  

var observable = new Subject<Bar>();
_components.WithSsoToken(_configuration.SsoToken)
    .Get(@params)
    .Select(Map)
    .Subscribe(c =>
    {
        _cache.Add(@params, c);
        observable.OnNext(c);
        observable.OnCompleted();
    }, exception =>
    {
        observable.OnError(exception);
    });

return observable.AsObservable();

答案 1 :(得分:2)

方便的是,我写了一个为你做这种模式的课程,请查看:

https://github.com/xpaulbettsx/ReactiveXaml/blob/master/ReactiveXaml/ObservableAsyncMRUCache.cs

var cache = new ObservableAsyncMRUCache<int, int>(
    x => Observable.Return(x*10).Delay(1000) /* Return an IObservable here */, 
    100 /*items to cache*/,
    5 /* max in-flight, important for web calls */
    );

IObservable<int> futureResult = cache.AsyncGet(10);

futureResult.Subscribe(Console.WriteLine);
>>> 100

它正确处理的一些棘手的事情:

  • 它缓存最后n个项目并丢弃未使用的项目
  • 确保不会同时运行n个项目 - 如果不这样做,如果缓存为空,则可以轻松生成数千个Web调用
  • 如果连续两次要求同一项目,第一个请求将发起请求,第二个请求将等待第一个请求而不是产生相同的请求,因此您不会最终冗余地查询数据