W Rx, jak grupować zdarzenia według id i ograniczać każdą grupę wieloma TimeSpans?

Tak się stało, że wpadłem w szał Rx i to pytanie jest związane z moimtutaj itutaj. Niemniej jednak, może to być pomoc dla kogoś, ponieważ widziałem je jako przydatne wariacje tego samego tematu.

Pytanie: Jak można pogrupować losowy strumieńint (powiedzmy na interwałach [0, 10] generowanych w losowym interwale) obiekty w grupy i zapewniają grupie earch zmienną liczbę nieobecności alarmów o zdarzeniach (ze względu na brak lepszej definicji, aby dalsze tło zobaczyć połączone posty). Dokładniej mówiąc, w jaki sposób można zdefiniować wielopunktowe ustawienia przepustnicy dla każdej grupy w następujący sposób:

var idAlarmStream = idStream
.Select(i => i)
.GroupByUntil(key => key.Id, grp => grp.Throttle(Timespan.FromMilliseconds(1000))
.SelectMany(grp => grp.TakeLast(1))
.Subscribe(i => Console.WriteLine(i));

Tutaj funkcja subskrypcji zostanie wywołana, jeśli nie ma więcej niż jednej sekundy braku identyfikatorów na grupę. Co by było, gdyby ktoś chciał zdefiniować trzy różne wartości braku wydarzeń (powiedzmy jedną sekundę, pięć sekund i dziesięć sekund) i wszystkie anulowane, gdy nadejdzie wydarzenie? Mogę myśleć o:

Podziel każdy identyfikatoridStream na kilka syntetycznych i zapewnić bijective mapowanie między prawdziwymi identyfikatorami i syntetycznymi. Na przykład w tym przypadku ID: 1 -> 100, 101, 102; ID: 2 -> 200, 201, 203, a następnie zdefiniuj funkcję selektora wThrottle takFunc<int, Timespan>(i => /* switch(i)...*/) a potem kiedySubscribe zostanie wywołany, odwzoruj identyfikator z powrotem. Zobacz także powiązane pytania dotyczące dalszego tła.Utwórz zagnieżdżone grupowanie, w którym identyfikatory są grupowane, a następnie grupy identyfikatorów zostaną skopiowane / zreplikowane / rozwidlone (nie znam właściwego terminu) w grupy zgodnie z wartościami ograniczającymi. Myślę, że takie podejście jest dość skomplikowane i nie jestem pewien, czy byłoby to najlepsze rozwiązanie. Byłbym jednak zainteresowany zainteresowaniem się takim zapytaniem.

Podejrzewam, że w bardziej ogólnym kontekście jest to sytuacja, w której istnieje wiele procedur obsługi dla jednej grupy, chociaż nie udało mi się znaleźć niczego z tym związanego.

<edytuj: Jako (miejmy nadzieję wyjaśnienie) przykładidStream naciska jeden identyfikator: 1, na którym zostaną zainicjowane trzy różne liczniki, z których każdy oczekuje na wystąpienie następnego zdarzenia lub alarmowanie, jeśli żaden nowy identyfikator 1 nie zostanie wykryty na czas. Licznik 1 (C1) oczekuje na pięć sekund, licznik 2 (C2) na siedem sekund i licznik 3 (C3) na dziesięć sekund. Jeśli nowy identyfikator 1 zostanie odebrany w przedziale [0, 5] sekund, wszystkie liczniki zostaną ponownie zainicjowane z wyżej wymienionymi wartościami i żaden alarm nie zostanie wysłany. Jeśli nowy identyfikator zostanie odebrany w przedziale [0, 7] sekund, alarmy C1 i C2 i C3 zostaną ponownie zainicjowane. Podobnie, jeśli nowy identyfikator zostanie odebrany w przedziale [0, 10] sekund ognia C1 i C2, ale C3 zostanie ponownie zainicjowany.

Oznacza to, że wystąpiłoby wiele „alarmów o nieobecności” lub ogólnie, podjętych działań, w kierunku jednego identyfikatora, pod warunkiem pewnych warunków. Nie jestem pewien, jaki byłby dobry analog ... Być może układanie „świateł ostrzegawczych” w wieży, aby najpierw było zielone, potem żółte i wreszcie czerwone. Ponieważ brak identyfikatora trwa dłużej i dłużej, kolor po kolorze zostanie podświetlony (w tym przypadku czerwony jest ostatnim). Następnie po wykryciu jednego identyfikatora wszystkie światła zostaną wyłączone.

<edytuj 2: Po doposażeniu kodu Jamesa w poniższy przykład i pozostawieniu reszty w formie pisemnej odkryłemSubscribe zostanie wywołany bezpośrednio po pierwszym zdarzeniu na obu poziomach alarmów.

const int MaxLevels = 2;
var idAlarmStream = idStream
    .Select(i => i)
    .AlarmSystem(keySelector, thresholdSelector, MaxLevels, TaskPoolScheduler.Default)
    .Subscribe(i =>
    {
        Debug.WriteLine("Alarm on id \"{0}\" at {1}", i, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
    });

Zobaczmy, co się tutaj dzieje i czyMaxLevels może być dostarczany dynamicznie ...

<edit 3: Kod Jamesa działa. Problem leżał między krzesłem a klawiaturą! Zmiana czasu na coś bardziej sensownego na pewno pomogła. W rzeczywistości zmieniłem je na większe postacie, ale tak było.FromTicks i uciekł mi przez kilka minut.

questionAnswers(1)

yourAnswerToTheQuestion