C# Reactive Extensions - 内存管理和 Distinct 运算符 [英] C# Reactive Extensions - Memory management and the Distinct operator

查看:25
本文介绍了C# Reactive Extensions - 内存管理和 Distinct 运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例代码:

   public static IObservable<Order> ObserveOrders(this IProxy proxy,IEqualityComparer<Order> distinctPerDayComparer )
   {
        return Observable.FromEvent<Order>(ev => proxy.OrderUpdated += ev,ev => proxy.OrderUpdated -= ev)
                    .Distinct(distinctPerDayComparer);
   } 

   public class DistinctPerDayComparer : IEqualityComparer<Order>
   {
        public bool Equals(Order o1, Order o2)
        {
            if(o1.Id != o2.Id)
               return false;

            bool isSameDay = o1.Date.Day == o2.Date.Day;
            return isSameDay;
        }            

        public int GetHashCode(Order o)
        {
           return o.Id.GetHashCode();
        }
   }

public class Order
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
} 

场景:

序列:

 {id:1,D:'5/25/2016'}-{id:1,D:'5/25/2016'}-{id:2,D:'5/25/2016'}-{id:1 ,D:'5/26/2016'}

不同的序列:

 {id:1,D:'5/25/2016'}-{id:2,D:'5/25/2016'}-{id:1,D:'5/26/2016'}

现在假设这个序列是长时间运行的,实际上 onComplete 从未被调用过.

Now assume that this sequence is long running, in fact onComplete is never called.

Rx 如何管理它以便它不会在内存中保存所有不同的元素以进行比较?

How does Rx manage it so it does not hold all the distinct elements in memory to compare with ?

我猜它为其管道中的元素保留了一些后备存储.但我总是认为在使用下一个项目调用 onNext 之后,该项目被简单地处理掉.

I'm guessing it holds some back storage for elements in it's pipeline. but i always figured that after onNext is called with the next item that item is simply disposed.

仍然如果它被释放了,那么在调用 Distinct 运算符时,Rx 将哪些元素用于 EqualityComparer ?

Still if it's disposed what elements does Rx use for the EqualityComparer when calling the Distinct operator ?

推荐答案

如果您查看 Rx 源代码,您会发现 distinct 使用了一个哈希集并将值存储在那里.您认为项目只是被处置的假设是不正确的.

If you look at the Rx source code you will find that distinct is using a hashset and storing the values in there. Your assumption that item is simply disposed isn't correct.

如果您的订单对象很重,您可以使用键选择器,而 RX 只会将该值存储在哈希集中.

If your order objects are heavy you can use the keyselector and RX will just store that value in the hashset.

.Distinct(o => Tuple.Create(o.id, o.Date), distinctPerDayComparer);

则需要更改 distinctPerDayComparer

then distinctPerDayComparer will need to be changed

public class DistinctPerDayComparer : IEqualityComparer<Tuple<int, DateTime>>
{
    public bool Equals(Tuple<int, DateTime> o1, Tuple<int, DateTime> o2)
    {
        if(o1.Item1 != o2.Item1)
           return false;

        bool isSameDay = o1.Item2.Day == o2.Item2.Day;
        return isSameDay;
    }            

    public int GetHashCode(Tuple<int, DateTime> o)
    {
       return o.Item1.GetHashCode();
    }
}

没有测试代码,但应该是一个起点.现在将存储元组,直到序列完成,而不是您的 Order 对象.

didn't test the code but should be a starting place. Will now store Tuples until the sequence is complete instead of your Order objects.

否则,您可以使用 Window 函数将它们分组并按计划清理它们,但对于整个可观察序列而言,它并不是真正不同的.

Otherwise you could use the Window function to group them and clean them up on a schedule but then it's not truly distinct for the entire observable sequence.

这篇关于C# Reactive Extensions - 内存管理和 Distinct 运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆