Реактивные расширения Обновление пользовательского интерфейса - PullRequest
3 голосов
/ 27 февраля 2011

Я делаю этот асинхронный вызов веб-запроса несколько раз (может быть дважды, трижды или даже 6 раз в зависимости от условий)

        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); });

У меня есть коллекция (список) во ViewModel, которая имеет привязку к LisBox, и я хотел бы продолжать добавлять в коллекцию после каждого ответа.

Каков наилучший способ сделать это с помощью Reactive Extensions? Было бы здорово, если бы кто-нибудь показал мне пример кода!

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 02 марта 2011

В ReactiveUI , это делается с помощью 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 обрабатывает весь материал ObserveOn, чтобы убедиться, что он синхронизирован и находится в нужных потоках и т. Д. Этот вызов немедленно возвращается с пустым списком, а затем, когда приходят результаты, коллекция заполняется.

2 голосов
/ 27 февраля 2011

Вы можете перевести поток URL-адресов непосредственно в потоки:

    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();
    }

И затем вам нужно наблюдать за своими ответами на интерфейсе, вам нужно использовать .ObserveOnDispatcher (), например:

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