Reputation: 738
Using Reactive.NET, how can I wait until the same event has happened for n seconds before performing an action?
The following sample (C#, WinForms) is doing what I want, but I want a delay (let say 1 second) before the expanding happens:
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();
});
Upvotes: 1
Views: 697
Reputation: 7919
I believe you're looking for 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();
});
Note:
tree.GetNodeFromCoordinates()
twice, I have used it with the Select
operator to bring it through to the subscriptionDistinctUntilChanged
to block repeated node selection events if the node is the sameObserveOn
operator to after the Throttle
call to avoid blocking the thread - general guidelines for ObserveOn
suggest that you should leave it as the last operator before your subscription. If you do need to use SynchronizationContext.Current
for tree.GetNodeFromCoordinates()
then you might need to switch schedulers a few times to avoid cross-threading exceptions.Upvotes: 2