2017-09-21 5 views
0

RX.net .Throttle() '슬라이딩' 나는 평소, 연속해서 일어날 수있는 이러한 이벤트로 이제내가 어느 정도 정상적인 조절 이상으로 조금 이동 관찰 스트림을위한 특별한 필요/요구 사항으로 가지고 있고 그것을 수행하는 방법에 완전히 확실하지 않다 창

var someEventObservable = Observable.FromEventPattern<SomeEventHandler, SomeEventArgs>(
    handler => this.ColumnWidthChanged += handler, 
    handler => this.ColumnWidthChanged -= handler) 
    .Select(_ => Unit.Default); 

나는 단지 그것을 주어진 시간 내에 한 번 이상 발생 여부를 알 필요가 : 나는 관찰과 같이 일반적인 이벤트에서 원래 스트림을 .Throttle()을 사용하십시오. 예 :

var someThrottledEventObservable = someEventObservable 
    .Throttle(TimeSpan.FromMilliseconds(300)); 

그러나 실제 요구 사항은 한 걸음 더 나아갑니다. 이벤트가 해당 시간 제한 TimeSpan/dueTime 내에서 발생하고 다른 이벤트가 첫 번째 이벤트 이후에 발생했지만 여전히 dueTime 내에 발생하면 조절 된 스트림을 0 시간을 다시 기다렸다가 또 ​​다른 300ms를 기다리십시오. 다른 이벤트가 발생하면 다시 시작/연장하십시오 .. 등등. 원본 또는 다시 시작된 TimeSpan/dueTime 내에서 다른 이벤트가 발생하지 않은 경우에만 someThrottledEventObservable은 새 Unit 인스턴스를 생성해야합니다.

기본적으로 조절 스트림의 대기 시간 내에 새로운 이벤트가 발생하면 주어진 시간 동안 새로운 이벤트가 발생하지 않도록 소스 스트림이 중단 될 때마다 하나의 이벤트를 생성하는 조절 된 스트림의 이벤트가 필요합니다. 기다리는 것을 다시 시작해야합니다.

또는 계속 진행되는 '폭풍우'이벤트에서 .Throttle() 만 단독으로 300 밀리미터 (위의 예에서는)마다 새로운 단위를 산출하지만, 하나 이상의 이벤트가 해고 될 때마다 정확히 하나의 새로운 단위가 필요하지만 새로운 것이 없습니다. 이후 300ms의 쿨 다운 기간 내에 발생했다.

어떻게하면됩니까?

+1

하지만처럼 행동한다 스로틀 같은 소리 [샘플] (http://reactivex.io/documentation/operators/sample.html)이 아니라 [디 바운스 (HTTP 이상 : //reactivex.io/documentation/operators/debounce.html), 어떤 reactx.io는 연극에서의 작전이라고 주장합니다. 당신이 (문서를 기반으로) 설명했던 것처럼 Debounce _should_는 작동합니다. 질문에 대한 정당한 표현은 "Reactive Extensions for .NET에서 어떻게 디버깅합니까?"일 수 있습니다. – maxwellb

+1

스로틀은 이미 당신이 기대하는대로하고 있다고 생각합니다. 지정된 기간 후에 다른 이벤트가없는 경우에만 마지막 이벤트를 내 보냅니다. – nikoniko

+0

@nikoniko 예 - 여기 뭔가 잘못하고있을 것입니다 .. 확실하지 않은 이유가 있지만 문서를 다시 읽은 후에 명확하게 그것이 /해야 할 행동을해야한다고 명시되어 있습니다. 분명히 뭔가 다른 것들이 이벤트를 일으키고 있습니다./하나는 여러 번 처리됩니다. –

답변

0

@nikoniko가 이미 언급했듯이, 스로틀은 트릭을 할 것입니다. 소스에서 이벤트를 두 고주파에 도착하기 때문에 아무것도 결과

using System; 
using System.Reactive.Linq; 

namespace Printing { 
class Program { 
    static void Main(string[] args) { 
     var source = Observable.Interval(TimeSpan.FromMilliseconds(333)) 
      .Do(i => Console.WriteLine($"new item: {i}")); 
     var sampling = source.Throttle(TimeSpan.FromSeconds(1)) 
      .Do(i => Console.WriteLine($"sampled: {i}")); 

     var subscription = sampling.Subscribe(); 

     Console.ReadLine(); 

     subscription.Dispose(); 

     Console.ReadLine(); 
    } 
} 

} . 그러나 소스하다면 다음 시간 범위가 스로틀에서 주어진 요소를 제공하기 위해 더 많은 시간을 필요 시간을 조절하는 것은 끝난 후

using System; 
using System.Reactive.Linq; 

namespace Printing { 
    class Program { 
     static void Main(string[] args) { 
      var source = Observable.Interval(TimeSpan.FromSeconds(1.2)) 
       .Do(i => Console.WriteLine($"{DateTime.Now.ToShortTimeString()}: new item: {i}")); 
      var sampling = source.Throttle(TimeSpan.FromSeconds(1)) 
       .Do(i => Console.WriteLine($"{DateTime.Now.ToShortTimeString()}: {i}")); 

      var subscription = sampling.Subscribe(); 

      Console.ReadLine(); 

      subscription.Dispose(); 

      Console.ReadLine(); 
     } 
    } 
} 

결과가 나타납니다. 보시다시피 소스의 이벤트가 실행 된 후 두 번째로 결과에 표시됩니다.

08:32:26: new item: 0 
08:32:27: throttle 0 
08:32:28: new item: 1 
08:32:29: throttle 1 
08:32:30: new item: 2 
08:32:31: throttle 2 
08:32:32: new item: 3 
08:32:33: throttle 3 
08:32:34: new item: 4 
08:32:35: throttle 4 
08:32:36: new item: 5 
08:32:37: throttle 5 
rx.net 의미에 익숙하지