user636525
user636525

Reputation: 3200

Reactive Extensions Updating UI

I make this async webrequest call mutliple times(can be twice or thrice or even 6 times depending on conditions)

        var request = HttpWebRequest.CreateHttp(url);

        var observableRequest = Observable.FromAsyncPattern<WebResponse>(
            request.BeginGetResponse, request.EndGetResponse);

        Observable.Timeout(observableRequest.Invoke(), TimeSpan.FromSeconds(120)).
            Subscribe(response => { HandleListResult(response); },
            exception => { HandleListResultTimeOut(exception); });

I have a Collection (List) in the ViewModel which has a Binding to a LisBox and i would like to keep adding to the collection after each response returns.

What is the best practice to make this happen using Reactive Extensions ? Would be great if someone can show me some sample code !

Thanks in advance

Upvotes: 3

Views: 1135

Answers (2)

Ana Betts
Ana Betts

Reputation: 74654

In ReactiveUI, this is done via CreateCollection()

IObservable<string> source; // Maybe this is a Subject<string> or whatever

myBoundCollection = source
    .SelectMany(webServiceCall) // This is your FromAsyncPattern func
    .CreateCollection();  // Pipe the Observable to a Collection

ReactiveUI handles all of the ObserveOn stuff to make sure it's synchronized and on the right threads, etc. This call returns immediately with an Empty list, then as results come in, the collection gets populated.

Upvotes: 2

Sergey Aldoukhov
Sergey Aldoukhov

Reputation: 22744

You can translate url flow directly into streams:

    public static IObservable<Stream> RequestToStream(
        this IObservable<string> source, TimeSpan timeout)
    {
        return
            from wc in source.Select(WebRequest.Create)
            from s in Observable
                .FromAsyncPattern<WebResponse>(wc.BeginGetResponse,
                    wc.EndGetResponse)()
                .Timeout(timeout, Observable.Empty<WebResponse>())
                .Catch(Observable.Empty<WebResponse>())
            select s.GetResponseStream();
    }

And then you need to observe your responces on UI, you need to use .ObserveOnDispatcher(), f.e.:

        Observable
            .Return("www.msdn.com")
            .RequestToStream(TimeSpan.FromSeconds(1))
            .ObserveOnDispatcher()
            .Subscribe(request => UpdateUI(Request));

Upvotes: 2

Related Questions