建议在长时间运行的过程中使用rx distinct?

时间:2013-06-01 08:41:04

标签: c# system.reactive reactive-programming

我正在使用rx distinct运算符根据长时间运行的进程中的某个键过滤外部数据流。

这会导致内存泄漏吗?假设将收到许多不同的密钥。 rx distinct运算符如何跟踪以前收到的密钥?

我应该将groupbyuntil与持续时间选择器一起使用吗?

2 个答案:

答案 0 :(得分:5)

Observable.Distinct在内部使用HashSet。内存使用量大致与遇到的不同键的数量成正比。 (AFAIK约30 * n字节)

GroupByUntil做的事情与Distinct完全不同。
GroupByUntil(井)组,而Distinct过滤流的元素。

不确定预期用途,但如果您只想过滤连续相同的元素,则需要Observable.DistinctUntilChanged,其内存占用量与键数无关。

答案 1 :(得分:1)

这可能是一个有争议的策略,但如果您担心不同的密钥累积,并且如果有一个时间点可以安全地重置,您可以使用Observable.Switch引入重置策略。例如,我们有一个场景,每天都会重置“世界状况”,因此我们可以每天重置不同的可观察量。

Observable.Create<MyPoco>(
    observer =>
    {
        var distinctPocos = new BehaviorSubject<IObservable<MyPoco>>(pocos.Distinct(x => x.Id));

        var timerSubscription =
            Observable.Timer(
                new DateTimeOffset(DateTime.UtcNow.Date.AddDays(1)),
                TimeSpan.FromDays(1),
                schedulerService.Default).Subscribe(
                    t =>
                    {
                        Log.Info("Daily reset - resetting distinct subscription.");
                        distinctPocos.OnNext(pocos.Distinct(x => x.Id));
                    });

        var pocoSubscription = distinctPocos.Switch().Subscribe(observer);

        return new CompositeDisposable(timerSubscription, pocoSubscription);
    });

但是,我确实倾向于同意James World上面关于使用内存分析器进行测试的评论,以便在引入可能不必要的复杂性之前检查内存确实是一个问题。如果您正在累积32位整数作为密钥,那么在大多数平台上遇到内存问题之前,您将拥有数百万个唯一项。例如。 262144 32位int键占用1兆字节。可能是您在此时间之前很久重置了该过程,具体取决于您的方案。