《C#并发编程经典实例》—— 用限流和抽样抑制事件流

简介:

声明:本文是《C#并发编程经典实例》的样章,感谢图灵授权并发编程网站发布样章,禁止以任何形式转载此文。

问题

有时事件来得太快,这是编写响应式代码时经常碰到的问题。一个速度太快的事件流可导

致程序的处理过程崩溃。

解决方案

Rx 专门提供了几个操作符,用来对付大量涌现的事件数据。Throttle 和 Sample 这两个操 作符提供了两种不同方法来抑制快速涌来的输入事件。

Throttle 建立了一个超时窗口,超时期限可以设置。当一个事件到达时,它就重新开始计 时。当超时期限到达时,它就把窗口内到达的最后一个事件发布出去。

下面的例子也是监视鼠标移动,但使用了 Throttle,在鼠标保持静止 1 秒后才报告最近一 条移动事件。


private void Button_Click(object sender, RoutedEventArgs e)

{

Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(

handler => (s, a) => handler(s, a), handler => MouseMove += handler, handler => MouseMove -= handler)

.Select(x => x.EventArgs.GetPosition(this))

.Throttle(TimeSpan.FromSeconds(1))

.Subscribe(x => Trace.WriteLine(

DateTime.Now.Second + ": Saw " + (x.X + x.Y)));

}


输出结果依赖于鼠标的实际动作,我的测试结果是这样:

47: Saw 139

49: Saw 137

51: Saw 424

56: Saw 226

Throttle 常用于类似“文本框自动填充”这样的场合,用户在文本框中输入文字,当他停 止输入时,才需要进行真正的检索。为抑制快速运动的事件序列,Sample 操作符使用了另一种方法。Sample 建立了一个有规律 的超时时间段,每个时间段结束时,它就发布该时间段内最后的一条数据。如果这个时间 段没有数据,就不发布。

下面的例子捕获鼠标移动,每隔一秒采样一次。 与 Throttle 不同,使用 Sample 的例子中, 不需要让鼠标静止一段时间,就可要看到结果。


private void Button_Click(object sender, RoutedEventArgs e)

{

Observable.FromEventPattern>MouseEventHandler, MouseEventArgs>(

handler => (s, a) => handler(s, a), handler => MouseMove += handler, handler =>MouseMove -= handler)

.Select(x => x.EventArgs.GetPosition(this))

.Sample(TimeSpan.FromSeconds(1))

.Subscribe(x => Trace.WriteLine(

DateTime.Now.Second + ": Saw " + (x.X + x.Y)));

}


我先让鼠标静止几秒钟,然后连续移动,得到了下面的输出结果:

12: Saw 311

17: Saw 254

18: Saw 269

19: Saw 342

20: Saw 224

21: Saw 277

讨论

对于快速涌来的输入,限流和抽样是很重要的两种工具。别忘了还有一个过滤输入的简单方 法, 就 是 采 用 标 准 LINQ 的 Where 操 作 符。 可 以 这 样 说,Throttle 和 Sample 操 作 符 与

Where 基本差不多,唯一的区别是 Throttle、Sample 根据时间段过滤,而 Where 根据事件 的数据过滤。在抑制快速涌来的输入流时,这三种操作符提供了三种不同的方法 

目录
相关文章
|
6月前
|
数据可视化 数据挖掘
【因果推断】Day01- 实用计量方法图解与概述
【因果推断】Day01- 实用计量方法图解与概述
108 2
|
5月前
|
前端开发 UED
渐进增强和优雅降级之间的不同
渐进增强和优雅降级之间的不同
36 0
|
9月前
|
负载均衡 并行计算 算法
BWA序列比对方法丨针对较大基因组的并行计算和性能优化方式,利用多线程和负载均衡策略提高效率
BWA序列比对方法丨针对较大基因组的并行计算和性能优化方式,利用多线程和负载均衡策略提高效率
|
9月前
|
安全 UED
渐进增强和优雅降级之间的区别
渐进增强和优雅降级之间的区别
|
10月前
|
运维 算法
【信号变化检测】使用新颖的短时间条件局部峰值速率特征进行信号变化/事件/异常检测(Matlab代码实现)
【信号变化检测】使用新颖的短时间条件局部峰值速率特征进行信号变化/事件/异常检测(Matlab代码实现)
|
11月前
|
机器学习/深度学习 存储 人工智能
强化学习从基础到进阶-常见问题和面试必知必答[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
强化学习从基础到进阶-常见问题和面试必知必答[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
|
11月前
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战
强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战
|
11月前
|
机器学习/深度学习 人工智能 资源调度
强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
 强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
|
11月前
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶-常见问题和面试必知必答5::梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)
强化学习从基础到进阶-常见问题和面试必知必答5::梯度策略、添加基线(baseline)、优势函数、动作分配合适的分数(credit)
|
消息中间件 存储 缓存
五分钟搞懂分布式流控算法
五分钟搞懂分布式流控算法
320 0
五分钟搞懂分布式流控算法