c# – 使用Reactive Extensions轮询Web服务并绑定最后的x个结果

c# – 使用Reactive Extensions轮询Web服务并绑定最后的x个结果,第1张

概述我正在尝试将Reactive Extensions(Rx)用于一个看起来很合适的任务,以特定间隔轮询Web服务并显示其最后的x结果. 我有一个Web服务,它向我发送我想要监视的工具的状态.我想以特定的速率轮询此工具,并在列表中显示已轮询的最后20个状态. 所以我的列表就像是服务结果的“移动窗口”. 我正在使用Caliburn.Micro开发一个WPF应用程序,但我不认为这是非常相关的. 我到目前为 我正在尝试将Reactive Extensions(Rx)用于一个看起来很合适的任务,以特定间隔轮询Web服务并显示其最后的x结果.

我有一个Web服务,它向我发送我想要监视的工具的状态.我想以特定的速率轮询此工具,并在列表中显示已轮询的最后20个状态.

所以我的列表就像是服务结果的“移动窗口”.

我正在使用Caliburn.Micro开发一个WPF应用程序,但我不认为这是非常相关的.

我到目前为止得到的是以下内容(只是我快速入侵的示例应用程序,我不打算在真实应用程序中的Shellviewmodel中执行此 *** 作):

public class Shellviewmodel : Caliburn.Micro.PropertyChangedBase,IShell{    private ObservableCollection<string> times;    private string currentTime;    public Shellviewmodel()    {        times = new ObservableCollection<string>();        Observable            .Interval(TimeSpan.FromSeconds(1))            .SelectMany(x => this.GetCurrentDate().ToObservable())            .ObserveOndispatcher()            .Subscribe(x =>            {                this.CurrentTime = x;                this.times.Add(x);            });    }    public IEnumerable<string> Times    {        get        {            return this.times;        }    }    public string CurrentTime    {        get        {            return this.currentTime;        }        set        {            this.currentTime = value;            this.NotifyOfPropertyChange(() => this.CurrentTime);        }    }    private async Task<string> GetCurrentDate()    {        var clIEnt = new RestClIEnt("http://www.timeAPI.org");        var request = new RestRequest("/utc/Now.Json");        var response = await clIEnt.ExecuteGetTaskAsync(request);        return response.Content;    }}

在视图中,我只有一个绑定到CurrentTime属性的标签和一个绑定到Times属性的列表.

我的问题是:

>它不仅限于列表中的20个项目,因为我总是向ObservableCollection添加项目,但我找不到更好的数据绑定方法
> Interval不能像我想的那样工作.如果查询运行时间超过1秒,则将同时运行两个查询,我不希望这样做.我的目标是查询无限期地重复,但每秒的查询速度不超过1次.如果查询结束时间超过1秒,则应等待它完成并直接触发新查询.

第二次编辑:

下面的编辑是我愚蠢而且非常困惑,它会不断触发事件,因为Interval是一个永远不会结束的事物.布兰登的解决方案是正确的,并按预期工作.

编辑:

根据Brandon的例子,我尝试在linqPad中执行以下代码:

Observable    .Merge(Observable.Interval(TimeSpan.FromSeconds(2)),Observable.Interval(TimeSpan.FromSeconds(10)))    .Repeat()    .Scan(new List<double>(),(List,item) => { List.Add(item); return List; })    .Subscribe(x => Console.Out.Writeline(x))

我可以看到对控制台的写入每2秒发生一次,而不是每10次.因此,重复不会等待Observable在重复之前完成.

解决方法 试试这个:
// timer that completes after 1 secondvar intervalTimer = Observable    .Empty<string>()    .Delay(TimeSpan.FromSeconds(1));// querIEs one time whenever subscribedvar query = Observable.FromAsync(GetCurrentDate);// query + interval timer which completes// only after both the query and the timer// have expiredvar intervalquery = Observable.Merge(query,intervalTimer);// Re-issue the query whenever intervalquery completesvar queryLoop = intervalquery.Repeat();// Keep the 20 most recent results// Note.  Use an immutable List for this// https://www.nuget.org/packages/microsoft.bcl.immutable// otherwise you will have problems with// the List changing while an observer// is still observing it.var recentResults = queryLoop.Scan(    ImmutableList.Create<string>(),// starts off empty    (acc,item) =>    {        acc = acc.Add(item);        if (acc.Count > 20)        {            acc = acc.RemoveAt(0);        }        return acc;    });// store the resultsrecentResults    .ObserveOndispatcher()    .Subscribe(items =>    {        this.CurrentTime = items[0];        this.RecentItems = items;    });
总结

以上是内存溢出为你收集整理的c# – 使用Reactive Extensions轮询Web服务并绑定最后的x个结果全部内容,希望文章能够帮你解决c# – 使用Reactive Extensions轮询Web服务并绑定最后的x个结果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1244660.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存