0

I'm connecting to an object that asyncronously loads a collection of objects into an IEnumerable. At the time I connect, the IEnumerable may have items already in it's collection, and may add items during the lifetime of the application that I need to be notified of as they occur. As an example, it could be a bank account containing a list of bank transactions.

The challenge is this. I want to combine the processing of the initial values in the IEnumerable with any new additions. They are currently two processes. I would like to eliminate the use of NotifyCollectionChanged entirely.

I can modify the backend holding the IEnumerable. It does not need to remain as an IEnumerable if a solution to this question exists otherwise.

Random
  • 1,896
  • 3
  • 21
  • 33
  • You can use RX to subscribe to `NotifyCollectionChanged` if your collection supports it. You can't subscribe to `IEnumerable` as it's not an event. The question isn't that clear though, how many collections are there? Are you copying from one to another? – TheCodeKing Sep 01 '11 at 19:38
  • We're actually trying to eliminate the use of INotifyCollectionChanged in the source collection. In this scenario there are only two collections, a source and target. But this example is simplified from what's really going on. They are collections containing different types of objects, and a lot more going on. – Random Sep 01 '11 at 19:54
  • I guess it's difficult to know what you are after then RX is great for event based interactions. – TheCodeKing Sep 01 '11 at 19:57
  • Why get rid of INotifyCollectionChanged? Seems sort of arbitrary. Rx is meant to handle Event-Based things. If not INotifyCollectionChanged, what would be the source of events in this case? – Anderson Imes Sep 05 '11 at 03:54
  • I'm a little confused as to how this service of yours pumps values into an IEnumerable. Since this interface has no ability to be added to, would it be possible to post some sample code? Second question would be why are you wanting to eliminate INotifyCollectionChanged (and by extension an ObservableCollection)? This collection type seems perfect for your needs, unless I'm missing something obvious. – Ray Booysen Sep 08 '11 at 07:49

2 Answers2

2

I would suggest that the object should not expose a IEnumerable as that is for "cold observable values", where in your case you need something which can get additional items in future also.

The best way to model this would be to use ReplaySubject<T> instead of IEnumerable. Below is an example that demonstrate the situation similar of yours:

//Function to generate the subject with future values
public static ReplaySubject<int> GetSubject()
{
    var r = new ReplaySubject<int>();
    r.OnNext(1); r.OnNext(2); r.OnNext(3);
    //Task to generate future values
    Task.Factory.StartNew(() =>
    {
        while (true)
        {
            Thread.Sleep(3000);
            r.OnNext(DateTime.Now.Second);
        }
    });
    return r;
}

Consuming code:

var sub = GetSubject();
sub.Subscribe(Console.WriteLine);

Every time anyone subscribes to sub they will get all the values that have been published in the subject till now and as well as new values that this subject generates in future

Ankur
  • 33,367
  • 2
  • 46
  • 72
  • I have already mentioned in my answer that this is an example of using ReplySubject. The loop is just to keep pushing values in the subject. – Ankur Sep 02 '11 at 16:12
  • Yes I understand it, I'm just not keen on a poll based solution for an Rx problem. – TheCodeKing Sep 02 '11 at 17:08
  • This is not a poll based solution. No where in the code we are polling the items. The loop is sample code to publish items to the observable. Polling means checking a data source of new item availability which is not in this case. – Ankur Sep 03 '11 at 06:14
  • Sorry you're right I totally miss-understood - the dummy code in the implementation replaces the IObservableCollection. – TheCodeKing Sep 03 '11 at 10:01
  • +1 `ReplaySubject` is the right answer. The `while` loop is just noise - ignore that part of the answer. – Enigmativity Sep 06 '11 at 11:55
  • Yes, just use the OnNext method of the replay subject to add your new items as they arrive. each new subscriber will then get all the values which have been added to the replay subject straight away (in order) and will continue to recieve any new values. – ForbesLindesay Sep 07 '11 at 11:24
0

You can use Defer/Replay Operator

Rohit Sharma
  • 6,136
  • 3
  • 28
  • 47