0

我有一个方法叫做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 毫秒被调用一次,然后MonsterDeath每 1 秒被调用一次,但它不是那样工作的,MonsterDeath每 250 毫秒被调用一次,那么我该如何解决这个问题?

4

2 回答 2

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 调度程序。它们适用于简单的 Timer/Interval 调度。NewThread 似乎是完成这项工作的一把大锤子。
  4. 使用 _ 字符表示您没有使用参数。例如,调用 MonsterAction() 和 MonsterDeath 的动作可以更改为 (_=>MonsterAction())。这向下一个开发人员表示您实际上并未使用该参数。
  5. 我会将您的 DisposeMonsterAction/DisposeMonstersDeath 重命名为 MonsterActionSubscription 和 MonstersDeathSubscription。
  6. 我认为您不会从共享序列中获得任何收益。在幕后,真正在做这项工作的是调度程序。我实际上会想象每秒检查 4 次值实际上会比使用两个序列花费更多。

我建议为了你的队友(包括未来的你),这很简单,可以满足你的需要

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());
}
于 2013-01-22T12:28:23.383 回答
0

我不完全确定您为什么在这里使用“热”观察者(可能是由于其他代码?),但是像这样组合两个离散时间流的最简单方法是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();
}
于 2013-01-17T19:20:49.260 回答