1

我正在构建一个大量使用 RX 的 WP7 应用程序,但遇到了一个问题。添加大于 20 ms 的 Throttle 时,会显着降低性能。

下面的代码片段指出了这个问题:

var moveObs = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
                    h => this.MouseMove += h,
                    h => this.MouseMove -= h);

// Observe dragging
var yObs = (from x in moveObs
            select -(x.EventArgs.GetPosition(this).Y - _initY));

var result = yObs.SkipWhile(y => !_isDragging)
                 .Throttle(TimeSpan.FromMilliseconds(33));

result.TimeInterval()
      .Subscribe(x => Debug.WriteLine("Mouse move interval: " + x));

这是代码段的输出:

'UI Task' (Managed): Loaded 'Microsoft.Devices.Sensors.dll'
The thread '<No Name>' (0x1e18) has exited with code 0 (0x0).
Mouse move interval: 80@00:00:04.1920000
Mouse move interval: -160@00:00:00.2900000
Mouse move interval: -126@00:00:00.6710000
The thread '<No Name>' (0x22a4) has exited with code 0 (0x0).
Mouse move interval: -90@00:00:01.0460000
The thread '<No Name>' (0x2514) has exited with code 0 (0x0).
Mouse move interval: -113@00:00:00.3250000
The thread '<No Name>' (0x270c) has exited with code 0 (0x0).
Mouse move interval: 108@00:00:12.1420000
The thread '<No Name>' (0x186c) has exited with code 0 (0x0).
Mouse move interval: 221@00:00:01.4860000

所以据我了解,Throttle 将从线程池创建一个线程并且不会阻塞 UI,它应该非常有效,不是吗?

问题 那么为什么性能这么慢。我是 RX 的新手,所以我可能在这里遗漏了一些东西。

编辑

这是另一个重现相同问题的示例:

var oneNumberPerSecond = Observable.Interval(TimeSpan.FromMilliseconds(10));

var lowNums = from n in oneNumberPerSecond
              select n;


lowNums.Throttle(TimeSpan.FromMilliseconds(100))
       .TimeInterval()
       .Subscribe(lowNum => Debug.WriteLine(lowNum));

据我了解,这应该每 100 毫秒打印一个数字,但它不会打印任何数字。

4

1 回答 1

2

并不是说它很慢-您所描述的正是 Throttle 的行为。

当流在指定的持续时间内停止生成值时,Throttle 会生成一个值。

让我分解你的复制品:

var oneNumberPerSecond = Observable.Interval(TimeSpan.FromMilliseconds(10));

这是一个冷观测值,每 10 毫秒产生一个值。

var lowNums = from n in oneNumberPerSecond
              select n;

这真的没什么。相当于oneNumberPerSecond.Select(i => i)

lowNums.Throttle(TimeSpan.FromMilliseconds(100))

这将产生一个流,该流将在lowNums停止产生 100 毫秒的值时产生一个值。但是由于lowNums每 10 毫秒产生一个值,所以不会有 100 毫秒内什么都没有发生的时候。

于 2012-01-20T19:11:27.910 回答