Проблема обнаружения наблюдаемого OnCompleted в RX - PullRequest
0 голосов
/ 04 июля 2011

У меня проблема с обнаружением действия onComplited в RX. Я загружаю данные в ListBox из веб-службы.

Основная ситуация работает отлично: - "Complited item" находится внизу

App.ViewModel.LoadData();

IObservable<WebServiceClass.ItemGetValues> observable = App.ViewModel.Items
   .ToObservable(Scheduler.NewThread);

var items = new ObservableCollection<WebServiceClass.ItemGetValues>();
ListBox1.ItemsSource = items;

observable.ObserveOnDispatcher().Subscribe(
    item => { items.Add( new WebServiceClass.ItemGetValues(item.nazwa, item.skrot, item.id) ); },
    () => { items.Add( new WebServiceClass.ItemGetValues("Complited", "", "") ); }
);

Но когда я вызываю веб-сервис для каждого элемента с кодом ниже, «Complited item» сначала добавляется

App.ViewModel.LoadData();

IObservable<WebServiceClass.ItemGetValues> observable = App.ViewModel.Items
   .ToObservable(Scheduler.NewThread);

var items = new ObservableCollection<WebServiceClass.ItemGetValues>();
ListBox1.ItemsSource = items;

observable.ObserveOnDispatcher().Subscribe
    (item =>
        {
            //items.Add(item);
            var request = Observable.FromAsyncPattern<string, string>(client.BeginGetLastValue, client.EndGetLastValue);
            request(item.skrot).ObserveOnDispatcher().Subscribe(
                    (it) =>
                    {
                        Func<string, WebServiceClass.ItemGetValues> deserializeFirst = r =>
                                        ((List<WebServiceClass.ItemGetValues>)JsonConvert
                                        .DeserializeObject(r,
                                            typeof(List<WebServiceClass.ItemGetValues>)))
                                        .First();
                        item.zm_dzienna = deserializeFirst(it).zm_dzienna;
                        items.Add(item);
                    }
            );
        },
    () => { items.Add(new WebServiceClass.ItemGetValues("Complited", "Complited", "0")); }
    );

Как правильно определить действие onComplited?


Решение

Проблема с исключением nullReference в функции deserializeFirst.

App.ViewModel.LoadData();

IObservable<WebServiceClass.ItemGetValues> observable = App.ViewModel.Items
    .ToObservable(Scheduler.NewThread);

var items = new ObservableCollection<WebServiceClass.ItemGetValues>();
ListBox1.ItemsSource = items;

var request = Observable.FromAsyncPattern<string, string>(client.BeginGetLastValue, client.EndGetLastValue);

observable.SelectMany(
    item => request(item.skrot).Select(it => {
                                                Func<string, WebServiceClass.ItemGetValues> deserializeFirst = r =>
                                                ((List<WebServiceClass.ItemGetValues>)JsonConvert
                                                .DeserializeObject(r,
                                                    typeof(List<WebServiceClass.ItemGetValues>)))
                                                .First();
                                                item.zm_dzienna = deserializeFirst(it).zm_dzienna;
                                                return item; 
                                                })
    ).SubscribeOnDispatcher().Subscribe(
            result => { Dispatcher.BeginInvoke(delegate { items.Add(result); }); },
            () => { Dispatcher.BeginInvoke(delegate { items.Add(new WebServiceClass.ItemGetValues("c","c","c")); }); }
        );

С наилучшими пожеланиями, Лукаш

1 Ответ

1 голос
/ 05 июля 2011

Вам нужно перетащить внутренний запрос в последовательность Rx, а не запускать его из вашей подписки. Это дает вам возможность Rx, компоновки и тестируемости. И дает вам результаты, которые вы хотите.

Это начало того, что нужно.

Func<string, WebServiceClass.ItemGetValues> deserializeFirst = r =>
        ((List<WebServiceClass.ItemGetValues>)JsonConvert
        .DeserializeObject(r,typeof(List<WebServiceClass.ItemGetValues>)))
        .First();
var request = Observable.FromAsyncPattern<string, string>(client.BeginGetLastValue, 
                                                          client.EndGetLastValue);
observable
    .SelectMany((item) => request(item.skrot))
    .Select((it) => item.zm_dzienna = deserializeFirst(it).zm_dzienna)
    .ObserveOnDispatcher()
    .Subscribe(
        item => items.Add(item), 
        () => items.Add(new WebServiceClass.ItemGetValues("Complited", "Complited", "0")));
...