Wpf 使用RX减少鼠标移动事件的频率

Wpf 使用RX减少鼠标移动事件的频率,wpf,events,mouse,system.reactive,Wpf,Events,Mouse,System.reactive,我是RX的新手,但觉得它应该能够为我想要解决的任务提供一个很好的解决方案。经过相当多的搜索,我仍然没有找到解决办法 我有一个WPF应用程序,其中一个控件对一些鼠标移动事件进行响应。我想降低事件的频率,这样当用户在控件上移动鼠标时,处理程序的调用频率就会比当前低。理想情况下,我想要的是设置并订阅一个观察者。观察者应该观察鼠标移动事件,并在特定时间窗口(例如0.2秒)过后,使用最新的事件和参数调用客户机代码。作为RX的新手,我首先用一个观察者替换了我原来的标准事件连接,如下所示: var mouse

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

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

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

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 
这似乎很管用

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

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

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

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 
从读数来看,节流阀似乎会吞下事件,直到频率下降到某个特定阈值以下,这与我预期的不太一样,而我相信样本会定期对观察到的事件进行采样?我希望客户端代码能够在给定的时间间隔内获得最新的事件。如果在该时间间隔内未记录任何事件,则不应调用客户端

希望有人能在这方面帮助RX新手

哦,我还想知道在控件的生命周期内鼠标移动频率的降低


Max

我认为您使用样本的方法是正确的-具体来说,这对您没有什么好处

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));}));
}

我认为您使用样本的方法是正确的-具体来说,这对您没有什么好处

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));}));
}

它可以正常工作,但我现在经常看到杀死我的应用程序的异常:System.Responsive.Core.dll中发生了“System.InvalidOperationException”类型的第一次意外异常。崩溃发生在鼠标按下事件处理程序中。这只发生在我使用鼠标移动的示例调用时。啊,看起来像是线程问题。我需要做这件事BeginInvoke@MaxPalmer或者,您可以使用ObserveOnDispatcher并删除BeginInvoke调用:var disp=mouseMove.ObserveOnDispatcher.Subscribeargs=>myControl\u MouseMoveargs.Sender,args.EventArgs;它可以正常工作,但我现在经常看到杀死我的应用程序的异常:System.Responsive.Core.dll中发生了“System.InvalidOperationException”类型的第一次意外异常。崩溃发生在鼠标按下事件处理程序中。这只发生在我使用鼠标移动的示例调用时。啊,看起来像是线程问题。我需要做这件事BeginInvoke@MaxPalmer或者,您可以使用ObserveOnDispatcher并删除BeginInvoke调用:var disp=mouseMove.ObserveOnDispatcher.Subscribeargs=>myControl\u MouseMoveargs.Sender,args.EventArgs;