问题在RX中检测到可观察的OnCompleted

时间:2011-07-04 12:51:35

标签: web-services windows-phone-7 system.reactive

我在RX中检测onComplited动作时遇到问题。 我正在从Web服务向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", "", "") ); }
);

但是,当我使用下面的代码为每个项目调用Web服务时,首先添加“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操作?

<小时/>

解决方案

deserializeFirst func中的nullReference异常问题。

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 个答案:

答案 0 :(得分:1)

您需要将内部查询拉入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")));