【问题标题】:Observable.Defer - need some clarification as to what exactly it doesObservable.Defer - 需要澄清一下它到底做了什么
【发布时间】:2012-07-12 18:38:11
【问题描述】:

假设我想生成一个异步随机数流,每 100 毫秒抽出一个新值。在尝试提出解决方案时,我的第一次尝试看起来像这样:

        var random = new Random();
        Observable.Start(() => random.Next())
                  .Delay(TimeSpan.FromMilliseconds(100))
                  .Repeat()
                  .Subscribe(Console.WriteLine);

如果您尝试运行它,您会注意到它只是一遍又一遍地重复相同的值。好的,我想我误解了重复的工作原理。在玩了一会儿之后,我想出了这个并且它起作用了:

        var random = new Random();
        Observable.Defer(()=> Observable.Start(() => random.Next()))
                  .Delay(TimeSpan.FromMilliseconds(100))
                  .Repeat()
                  .Subscribe(Console.WriteLine);

所以我去 MSDN 文档了解 Defer 实际在做什么,这就是它所说的:

返回调用可观察工厂的可观察序列 每当有新的观察者订阅时。

我想我的困惑是:在我的代码示例中,我只订阅了 Observable 一次,那么为什么它似乎一遍又一遍地调用 Observable.Start(...) 呢?还是我误会Repeat()?任何澄清都会很棒。

【问题讨论】:

    标签: c# .net system.reactive


    【解决方案1】:

    你误会了重复。基本上,Repeat 会在每次完成时继续重新订阅一个 observable。

    Observable.Start 显然会在您第一次调用订阅时缓存该值,并在您每次订阅时返回它。这就是第一个示例中反复出现相同数字的原因。

    延迟的工作原理如下:

    IObservable<T> Defer(Func<IObservable<T>> factory)
    {
        return Observable.Create<T>(obs => factory().Subscribe(obs));
    }
    

    所以每次订阅Defer observable 时,它​​都必须调用factory 函数。在这种情况下,工厂创建了一个 new observable,从而避免了 Start 的缓存行为。

    获取您描述的序列的另一种方法是使用Interval 获取您的时间,使用Select 获取随机数。

    Observable.Interval(TimeSpan.FromMilliseconds(100))
              .Select(i => random.Next())
              .Subscribe(Console.WriteLine);
    

    【讨论】:

      【解决方案2】:

      “生成”随机数的一种简单方法是使用.Generate。试试这个:

      var rnd = new Random();
      
      Observable
          .Generate(
              0,
              x => true,
              x => x,
              x => rnd.Next(),
              x => TimeSpan.FromMilliseconds(100.0))
          .Subscribe(n => { });
      

      【讨论】:

        猜你喜欢
        • 2017-01-18
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 2022-11-10
        • 2016-08-10
        相关资源
        最近更新 更多