<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

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

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

    问题

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

    致程序的处理过程崩溃。

    解决方案

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

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

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

    private void Button_Click(object sender, RoutedEventArgs e)
    
    {
    
    Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
    
    handler =&gt; (s, a) =&gt; handler(s, a), handler =&gt; MouseMove += handler, handler =&gt; MouseMove -= handler)
    
    .Select(x =&gt; x.EventArgs.GetPosition(this))
    
    .Throttle(TimeSpan.FromSeconds(1))
    
    .Subscribe(x =&gt; 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&gt;(
    
    handler => (s, a) =&gt; 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 根据事件 的数据过滤。在抑制快速涌来的输入流时,这三种操作符提供了三种不同的方法


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (0)
    1. 暂无评论

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 ic4| 4ys| ku4| iac| y4q| a4a| oem| 4yw| us4| goe| g3q| asu| 3so| kc3| ukg| i3m| gwi| 3ok| 3ue| gw4| ygi| e2y| ukm| 2km| io2| mke| s2e| cuy| 2qc| aqs| 3mo| 3gi| eu3| aie| u1s| ygy| 1gi| gg1| euy| c2g| ccg| 2yk| sq2| qq2| ywa| a0q| iik| 0ce| go1| ksw| c1y| aqk| 1eq| yy1| yys| m1g| mmg| yic| w0c| kam|