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

C# 建议在长时间运行过程中使用rx distinct?,c#,system.reactive,reactive-programming,C#,System.reactive,Reactive Programming,我使用rx distinct运算符在长时间运行的进程中根据某个键过滤外部数据流 这会导致内存泄漏吗?假设会收到很多不同的密钥。rx distinct操作员如何跟踪以前收到的钥匙 我是否应该将GroupByUtil与持续时间选择器一起使用?可观察。Distinct在内部使用哈希集。内存使用量与遇到的不同键的数量大致成正比。(大约30*n字节) GroupByUntil做的事情与Distinct完全不同 GroupByUntil(好)分组,而Distinct过滤流中的元素 不确定其预期用途,但如果您

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

这会导致内存泄漏吗?假设会收到很多不同的密钥。rx distinct操作员如何跟踪以前收到的钥匙


我是否应该将GroupByUtil与持续时间选择器一起使用?

可观察。Distinct
在内部使用
哈希集。内存使用量与遇到的不同键的数量大致成正比。(大约30*n字节)

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


不确定其预期用途,但如果您只是想过滤连续的相同元素,则需要可观察的。DistinctUntilChanged
,它具有独立于键数的内存占用。

这可能是一种有争议的策略,但如果您担心不同键的累积,如果有一个时间点可以安全地重置,您可以使用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);
    });
Observable.Create(
观察员=>
{
var distinctPocos=新的行为主体(pocos.Distinct(x=>x.Id));
var timerSubscription=
可观测计时器(
新的DateTimeOffset(DateTime.UtcNow.Date.AddDays(1)),
时间跨度从天(1),
schedulerService.Default)。订阅(
t=>
{
Log.Info(“每日重置-重置不同的订阅”);
distinctPocos.OnNext(pocos.Distinct(x=>x.Id));
});
var pocoSubscription=distinctPocos.Switch().Subscribe(观察者);
返回新的CompositeDisposable(timerSubscription、pocoSubscription);
});

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

HashSet,而不是HashMap。在哈希集中,所有键都是唯一的。“对于非常大的HashSet对象,您可以通过在运行时环境中将gcAllowVeryLargeObjects配置元素的enabled属性设置为true,将64位系统上的最大容量增加到20亿个元素”。HashSet,而不是HashMap=>Fixed,thx,被困在Java universe3D抓取器的答案中(回答得很好),不要忽视显而易见的问题,也不要使用内存分析器测试代码。如果您担心内存泄漏,无论如何都应该这样做。如果您已经考虑过这一点,我深表歉意,但我经常发现人们对API中可能存在的泄漏感到困扰,而使用内存分析器几分钟就可以证明API是正确的,并在内存中发现漏洞他们自己的代码。:)至少您可以测量特定场景的特征。谢谢james,我接受了您的建议,而且确实,在长时间运行的订阅上使用distinct运算符,distinct密钥上存在内存泄漏。然后,我们改为使用GROUPBY,直到关闭持续时间选择器,这解决了内存泄漏问题。