更改IConnectableObservable的间隔

时间:2013-01-17 18:08:18

标签: c# system.reactive reactive-programming

我有一个名为Subscribe()的方法,我这样做: -

private void Subscribe(){
            IObservable<long> timer = Observable.Interval(TimeSpan.FromMilliseconds(250), Scheduler.NewThread);
            IConnectableObservable<long> TimerPublisher = timer.Publish();
            TimerPublisher.Connect();

            this.DisposeMonsterAction = TimerPublisher.Subscribe(tick => MonsterAction());

            var timer = from tick in world.TimerPublisher where tick % 1 == 0 select tick;
            this.DisposeMonstersDeath = timer .Subscribe(tick => MonstersDeath());
}

这样MonsterAction()每隔250毫秒调用一次,然后{1}}每隔1秒调用一次,但它不是那样工作,MonsterDeath每250毫秒被调用一次,所以如何解决这个问题呢?问题

2 个答案:

答案 0 :(得分:0)

我不完全确定你为什么使用&#34; hot&#34;这里可观察到(可能是由于其他代码?),但是像这样组合两个离散时间流的最简单方法是使用Merge

Action MonsterAction = 
    () => Console.WriteLine("MonsterAction");
Action MonsterDeath = 
    () => Console.WriteLine("MonsterDeath");

// action stream
var monsterAction = Observable
    .Interval(TimeSpan.FromMilliseconds(250))
    .Do(_ => MonsterAction());

// death stream
var monsterDeath = Observable
    .Interval(TimeSpan.FromMilliseconds(1000))
    .Do(_ => MonsterDeath());

// act, act, act, act + die, act, act, ...
var obs = monsterAction.Merge(monsterDeath);

// "warm up" the cold observable
var hotObs1 = obs.Publish();

using(var conn = hotObs1.Connect())
using(var x = hotObs1.Subscribe(evt => Console.WriteLine(evt)))
{
    Console.ReadLine();
}

答案 1 :(得分:0)

忽略间隔序列的相当奇怪的共享和使用NewThread,你的问题似乎完全在于

where tick % 1 == 0

我只能想象需要阅读

where tick % 4 == 0 //or ==3 or whatever...

即,任何整数/长值除以1的余数为0,因此你的where子句是没有意义的。

您可能会觉得有用的其他提示:

  1. 在连接之前填写订阅。即如果继续使用Connectable observable,则将.Connect()行作为方法的最后一行。
  2. 考虑注入您正在使用的调度程序,以便进行测试
  3. 考虑使用Task或ThreadPool调度程序。它们适用于简单的定时器/间隔调度。对于这项工作来说,NewThread似乎是一把大锤子。
  4. 使用_字符表示您没有使用参数。例如。您调用MonsterAction()和MonsterDeath的Action可以更改为(_ =&gt; MonsterAction())。这向下一个开发人员表示您实际上并未使用该参数。
  5. 我会将您的DisposeMonsterAction / DisposeMonstersDeath重命名为MonsterActionSubscription&amp; MonstersDeathSubscription。
  6. 我不认为你从分享序列中获得任何好处。在引擎盖下,调度程序正在进行工作。我实际上可以想象,每秒检查4次值实际上比使用两个序列花费更多。
  7. 我建议为了你的队友(包括未来你),这很简单,足以满足你的需求

    private void Subscribe(IScheduler timerScheduler){
        this.DisposeMonsterAction = Observable.Interval(TimeSpan.FromMilliseconds(250), timerScheduler).Subscribe(_ => MonsterAction());
        this.DisposeMonstersDeath = Observable.Interval(TimeSpan.FromMilliseconds(1000), timerScheduler).Subscribe(_ => MonstersDeath());
    }
    

    或重命名

    private void Subscribe(IScheduler timerScheduler){
        this.MonsterActionSubscription = Observable.Interval(TimeSpan.FromMilliseconds(250), timerScheduler).Subscribe(_ => MonsterAction());
        this.MonstersDeathSubscription = Observable.Interval(TimeSpan.FromMilliseconds(1000), timerScheduler).Subscribe(_ => MonstersDeath());
    }