使用Rx等待,直到同一事件在一段时间内发生

本文关键字:事件 一段时间 等待 Rx 使用 | 更新日期: 2023-09-27 18:04:58

Using Reactive。. NET,我怎么能等到相同的事件发生了n秒之前执行一个动作?

下面的示例(c#, WinForms)正在做我想要的,但我想在展开发生之前延迟(假设1秒):

var autoExpand = Observable.FromEventPattern<DragEventArgs>(tree, "DragOver");
autoExpand
    .ObserveOn(SynchronizationContext.Current)
    .Distinct(dragEvent => tree.GetNodeFromCoordinates(dragEvent.EventArgs.X, dragEvent.EventArgs.Y))
    .Subscribe(dragEvent => {
            TreeNode node = tree.GetNodeFromCoordinates(dragEvent.EventArgs.X, dragEvent.EventArgs.Y);
            if (node != null) node.Expand();
        });

使用Rx等待,直到同一事件在一段时间内发生

我相信你是在找Throttle:

var autoExpand = Observable.FromEventPattern<DragEventArgs>(tree, "DragOver");
autoExpand
    .Select(dragEvent => tree.GetNodeFromCoordinates(dragEvent.EventArgs.X, dragEvent.EventArgs.Y))
    .DistinctUntilChanged()
    .Throttle(TimeSpan.FromSeconds(1))
    .ObserveOn(SynchronizationContext.Current)
    .Subscribe(node => {
            if (node != null) node.Expand();
        });

注意:

  • 为了避免两次生成tree.GetNodeFromCoordinates(),我将其与Select操作符一起使用,将其通过订阅
  • 如果节点是相同的,我们可以方便地使用DistinctUntilChanged来阻止重复的节点选择事件
  • 我已经将ObserveOn操作符移动到Throttle调用之后,以避免阻塞线程- ObserveOn的一般指南建议您在订阅之前将其作为最后一个操作符。如果你确实需要为tree.GetNodeFromCoordinates()使用SynchronizationContext.Current,那么你可能需要切换调度程序几次,以避免交叉线程异常。