2014-06-12 36 views
1

我正在尋找一個可觀察的擴展方法來做一個逆節流閥。我的意思是讓第一件商品通過,然後在適當的時候忽略商品後面的商品。逆Observable.Throttle

input - due time 2 
|*.*.*..*..| 
output 
|*......*..| 

請注意,這是一個不同於以下問題(它們都是相同的)的問題。下面的問題需要固定的抑制持續時間,而我需要抑制持續時間,每當新物品過早到達時就會增加抑制持續時間。直觀的解決方案,下面列出的輸出如下:

input - due time 2 
|*.*.*..*..| 
output 
|*...*..*..| 

UPDATE

我想出了以下的解決方案,但是我對調度程序和併發性知之甚少o確保鎖定足夠好。當方法中添加Scheduler參數時,我也不知道如何實現此方法。

public static IObservable<T> InverseThrottle<T>(this IObservable<T> source, TimeSpan dueTime) 
    { 
     IDisposable coolDownSupscription = null; 
     object subscriptionLock = new object(); 

     return source 
      .Where(i => 
      { 
       lock (subscriptionLock) 
       { 
        bool result; 
        if (coolDownSupscription == null) 
        { 
         result = true; 
        } 
        else 
        { 
         coolDownSupscription.Dispose(); 
         result = false; 
        } 

        coolDownSupscription = Observable 
          .Interval(dueTime) 
          .Take(1) 
          .Subscribe(_ => 
          { 
           lock (subscriptionLock) 
           { 
            coolDownSupscription = null; 
           } 
          }); 
        return result; 
       } 
      }); 
    } 

回答

3

您可以使用這樣的事情...

source 
    .GroupByUntil(
     x => Unit.Default, 
     x => x.Throttle(TimeSpan.FromSeconds(100)) 
    ) 
    .SelectMany(
     x => x.ToList().Take(1) // yields first item on completion of the observable. 
    ); 
+0

雖然油門不會「開火」,也許你想要Observable.Timer? –

+2

@PaulBetts當源流暫停爲100時,Throttle應該「激發」第一個項目。 – Brandon

+0

@PaulBetts。布蘭登是對的。當源流完成去抖動後,油門即將開始工作,這意味着將會產生一個額外的物品,直到它再次完成去除,等等。 –

0

我建議這一個。

public static class IObservable_FirstThenThrottle 
{ 
    public static IObservable<TSource> FirstThenThrottle<TSource>(this IObservable<TSource> source, TimeSpan dueTime) 
    { 
     var first = source.Take(1); 
     var second = source.Skip(1).Throttle(dueTime); 
     return first.Merge(second); 
    } 
} 

它會在第一個項目進入時觸發,然後通過dueTime節流剩餘的序列。

下面是一張大理石圖,顯示dueTime = 2會發生什麼情況。

source 0-1-2--3--| 
result 0------2--3--| 
+0

它似乎應該工作,但它不。輸出非常不規則。它還爲源代碼提供了一些時髦的東西,當我在開始時添加一個Do來打印每個項目時,第一個項目會出現兩次。 – Wouter