2

我是 RX 的新手,但我觉得它应该能够为我希望解决的任务提供一个很好的解决方案。经过相当多的搜索,我仍然没有找到解决方案。

我有一个 WPF 应用程序,其中一个控件执行一些工作以响应某些鼠标移动事件。我想降低事件的频率,以便处理程序的调用频率低于当前情况(因为用户在控件上移动鼠标)。理想情况下,我想要的是设置并订阅观察者。观察者应该观察鼠标移动事件,并在特定时间窗口过去后使用最近的事件和参数调用客户端代码,比如 0.2 秒。作为 RX 的新手,我首先用观察者替换了我原来的标准事件连接,如下所示:

var mouseMove = Observable.FromEventPattern<MouseEventArgs>(myControl, "MouseMove");

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 

这似乎工作正常。

然后我尝试修改观察者以获得我上面描述的行为。我尝试使用 Throttle() 调用和 Sample() 调用。这些并没有产生我预期(或渴望)的结果。事实上,在某些情况下,使用 Throttle/TimeSpan 调用的特定重载会导致我的应用程序死机,我仍然不明白。

这是我尝试过的一个例子:

var mouseMove = Observable.FromEventPattern<MouseEventArgs>(myControl, "MouseMove").Throttle(TimeSpan.FromSeconds(0.2));

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 

从阅读中,Throttle 似乎会吞下事件,直到频率降至特定阈值以下(与我预期的不太一样),而我相信 Sample 会定期对观察到的事件进行采样?我希望在给定的时间间隔内为客户端代码提供最新的事件。如果在该时间间隔内没有记录任何事件,则不应调用客户端。

希望有人可以帮助 RX 新手。

哦,我还想在控件的生命周期内随时了解(降低的频率)鼠标移动。

最大限度

4

1 回答 1

4

我认为你在正确的轨道上Sample- 具体来说,这对你没有什么作用?

示例 LINQPad 片段:

void Main()
{
    var window = new Window();
    window.Content = ctrl;
    window.Show();
    var mouseMove = Observable
        .FromEventPattern<MouseEventArgs>(window, "MouseMove")
        .Sample(TimeSpan.FromSeconds(0.2));
    var disp = mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs));     
    window.Closed += (o,e) => disp.Dispose();
}

ItemsControl ctrl = new ItemsControl();

// Define other methods and classes here
private void myControl_MouseMove(object sender, MouseEventArgs args)
{
    ctrl.Dispatcher.BeginInvoke((Action)(() => {ctrl.Items.Add(args.GetPosition(ctrl));}));
}
于 2013-01-31T20:03:54.600 回答