c# – 事件限制/排队 – 反应性扩展?

前端之家收集整理的这篇文章主要介绍了c# – 事件限制/排队 – 反应性扩展?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望在我的一个视图模型中实现一些限制行为.这是一个Silverlight应用程序,但我认为这不是特别重要.

考虑一个具有三个属性的类:

> Property1
> Property2
> Property3

每当更新其中一个属性时,都需要刷新.

private void Refresh()
{
    //Call out to the server,do something when it comes back
}

我的目标如下:

>如果正在进行刷新,我们应该理想地取消对服务器的调用,并发出新请求
>如果属性发生变化,我们应该留出一些小的时间窗口(可能是0.1秒),等待其他更改.这样,如果快速更改多个属性(例如,以编程方式),我们不会通过请求向服务器发送垃圾邮件. 0.1秒的窗口可以在每次更改时重置,但不是必需的.

如果重要,我正在使用ChannelFactory实现服务器调用.

我可以用什么样的模式来实现这个目标?这是反应性扩展可以帮助我的东西吗?

编辑:

将保罗的答案标记为正确.虽然ReactiveUI目前不支持silverlight5,但它清楚地概述了使用Rx解决问题的方法/组成步骤.

解决方法

以下是使用ReactiveUI执行此操作的方法
IObservable<TheData> FetchNewData() 
{
    // TODO: Implement me
}

this.WhenAny(x => x.Property1,x => x.Property2,x => x.Property3,(x,y,z) => Unit.Default)
    .Throttle(TimeSpan.FromMilliseconds(200),RxApp.DeferredScheduler)
    .Select(x => FetchNewData())
    .Switch()    // We only care about the req corresp. to latest values of Prop1-3
    .ToProperty(this,x => x.Data);

更新:以下是如何保证一次只运行一个,但需要注意的是,您可能会得到无序结果.

this.WhenAny(x => x.Property1,RxApp.DeferredScheduler)
    .Select(_ => Observable.Defer(() => FetchNewData()))
    .Merge(1)
    .ToProperty(this,x => x.Data);

您描述的行为实际上可能不太可取,因为如果属性不断变化,您最终将会发出旧请求的队列 – 如果您创建类似“BufferingSwitch()”运算符的内容,则可以对此进行优化在确定没有变化之前没有返回结果 – 这实际上很酷.

故事的道德,Async Is Complicated™:)

猜你在找的C#相关文章