2013-03-21 4 views
1

Использование Reactive.NET, как я могу подождать, пока одно и то же событие не произойдет за n секунд до выполнения действия?Подождите, пока не произойдет такое же событие в течение промежутка времени, используя Rx

Следующий пример (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(); 
     }); 
+0

Почему бы не использовать задачу и задачу и функции ContinueWith()? Он является родным .net – David

+1

Я еще не использовал Rx, но вы, вероятно, захотите [Delay] (http://msdn.microsoft.com/en-us/library/ff708297%28v=VS.92%29.aspx) после «Distinct». –

+0

@ David Я должен лениться написать код для обработки задержки, которую я ищу, поддерживая фоновый поток и т. Д. – Zurb

ответ

2

Я считаю, что вы ищете 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 предполагают, что вы должны оставить его последним оператором перед подпиской. Если вам нужно использовать SynchronizationContext.Current для tree.GetNodeFromCoordinates(), вам может понадобиться несколько раз переключать планировщики, чтобы избежать исключений перекрестных потоков.
+0

Да! Работает! Спасибо за оптимизацию! – Zurb

Смежные вопросы