无功扩展定时器/间隔复位

jon*_*boy 3 c# system.reactive

我有一个项目,我需要每10秒发送一次状态消息,除非在此期间有更新.意思是,每次有更新时,计时器都会重置.

var res = Observable
  .Interval(TimeSpan.FromSeconds(10))
  .Where(_ => condition);

res.Subscribe(_ => Console.WriteLine("Status sent."));
Run Code Online (Sandbox Code Playgroud)

现在我知道"Where"只会在计时器结束时应用,所以它没有帮助.但是,我想知道是否有办法重置间隔; 或者使用带有重复的Timer().

Eni*_*ity 5

使用标准Rx运算符很容易实现.

你的问题不清楚的是"更新"到底是什么.我将假设你有一些可观察到的每次更新都会触发,或者你可以创建一个.OnNext(...)在更新时你会调用的主题.如果没有可观察到的更新,很难知道何时重置计时器.

所以这是代码:

var update = new Subject<bool>();

var res =
    update
        .Select(x => Observable.Interval(TimeSpan.FromSeconds(10.0)))
        .Switch();

res
    .Subscribe(_ => Console.WriteLine("Status sent."));

update.OnNext(true);
Run Code Online (Sandbox Code Playgroud)

res查询现在等待,直到它从一个值update,然后选择一个新的Observable.Interval.这意味着Select在类型为a之后IObservable<IObservable<long>>,.Switch()需要将其转换为a IObservable<long>..Switch()这样做只是从最近观察到的观察值中输出值并处理任何先前的可观察量.换句话说,对于每个update新计时器启动并且取消先前的计时器.这意味着如果您的更新发生频率超过10秒,那么计时器将永远不会触发.

现在,如果resobservable本身就是一个更新,那么你可以这样做:

res
    .Subscribe(_ =>
    {
        update.OnNext(true);
        Console.WriteLine("Status sent.");
    });
Run Code Online (Sandbox Code Playgroud)

这很好 - 它仍然有效,但是对于每个定时器点火res将创建一个新的计时器.这意味着任何依赖于您的update可观察/主题的东西仍将正常运作.