加载wp7的RX和Web服务集合的问题

时间:2011-06-18 13:13:44

标签: c# windows-phone-7 service system.reactive

我是C#和wp7平台的初学者,我从Web服务获取请求时遇到了一些问题。

我在PHP(nusoap - WSDL)中创建了web服务,并且在“正常”使用时一切正常。 现在我在IsolatedStorage中保存了ObservableCollection,并在页面打开时加载(监视堆栈交换列表)。然后我想刷新Web服务中每个项目的数据。

我不知道这是不是一个好主意。

代码:

private GPWWebservicePortTypeClient client = new GPWWebservicePortTypeClient();
private ObservableCollection<WebServiceClass.ItemGetValues> StoredStock = 
                      new ObservableCollection<WebServiceClass.ItemGetValues>();     
public const string _fileName = "listaObserwowanych.xml";
public Page()
{
   InitializeComponent();

   DataContext = App.ViewModel;

   this.Loaded += new RoutedEventHandler(Page_Loaded);

   client.GetLastValueCompleted +=
            new EventHandler<GetLastValueCompletedEventArgs>(client_GetLastValueCompleted);

   foreach (var itemGetValuese in App.ViewModel.Items)
   {
      client.GetLastValueAsync(itemGetValuese.name);
   }

   var o = 
       Observable.FromEvent<GetLastValueCompletedEventArgs(client,"GetLastValueCompleted")
                                                           .Subscribe(setList);
}

void client_GetLastValueCompleted(object sender, GetLastValueCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show(Convert.ToString(e.Error));
    }
    else
    {
        ObservableCollection<WebServiceClass.ItemGetValues> ListValues = 
          (ObservableCollection<WebServiceClass.ItemGetValues>)                                                                      
           JsonConvert.DeserializeObject(e.Result, 
           typeof(ObservableCollection<WebServiceClass.ItemGetValues>));
        StoredStock.Add(ListValues[0]);
    }
}

private void setList(IEvent<GetLastValueCompletedEventArgs> ex)
{
    List.ItemsSource = StoredStock;
}


void Page_Loaded(object sender, RoutedEventArgs e)
{
    App.ViewModel.LoadData();
    List.ItemsSource = App.ViewModel.Items;
}

就像你看到我使用RX来调用方法client_GetLastValueCompleted将存储结果添加到辅助变量(StoredStock)。然后在setList方法中刷新List,但是那个方法是client_GetLastValueCompleted什么不太好主意,因为我只有在foreach中所有运行的GetLastValueAsync完成时才需要运行该方法。 第二个问题:因为异步Web服务方法,StoredStock有时会有比App.ViewModel.Items不同的订单。

有什么好主意如何以正确的方式做到这一点? 最好的问候,

的Lukas

2 个答案:

答案 0 :(得分:1)

如果您是C#的初学者,请暂时避免使用RX。这是一项很酷的技术,但是如果你在没有清楚了解正在发生的事情的情况下使用它,它将带来更多的问题而不是解决。

使用简单事件,当每个异步项到达时,找到并更新存储列表中的对应项。

答案 1 :(得分:1)

您真正混淆了多种方式来调用Web服务和Rx。你真的需要一个单一的决定并坚持下去。

如果您打算使用Rx,那么您将拥有以下内容:

public Page()
{
    InitializeComponent();

    DataContext = App.ViewModel;

    this.Loaded += new RoutedEventHandler(Page_Loaded);
}

void Page_Loaded(object sender, RoutedEventArgs e)
{
    App.ViewModel.LoadData();

    var storedStock =
        new ObservableCollection<WebServiceClass.ItemGetValues>();  

    List.ItemsSource = storedStock;

    var values =
        Observable.Using<WebServiceClass.ItemGetValues, GPWWebservicePortTypeClient>
            (() => new GPWWebservicePortTypeClient(), ws =>
            {
                var clientGetLastValue = Observable
                    .FromAsyncPattern<string, GetLastValueResponse>
                    (ws.BeginGetLastValue, ws.EndGetLastValue);

                Func<string, WebServiceClass.ItemGetValues> deserializeFirst = r =>
                    ((List<WebServiceClass.ItemGetValues>)JsonConvert
                    .DeserializeObject(r,
                        typeof(List<WebServiceClass.ItemGetValues>)))
                    .First();

                return
                    from item in App.ViewModel.Items
                    from e in clientGetLastValue(item)
                    select deserializeFirst(e.Result);
            });

    values.Subscribe(storedStock.Add);
}

您必须为您的Web服务客户端获取正确的方法调用名称,但代码应该大致正确。让我知道你是怎么走的。


我更正了上面的代码。应该在Using调用中返回查询,而不是将其分配给values


我更正了对FromAsyncPattern的调用,以使用正确的方法名称和通过电子邮件发送的实际Web服务引用类的返回类型。

它应该是这样的:

Observable.FromAsyncPattern<string, GetLastValueResponse>
    (ws.BeginGetLastValue, ws.EndGetLastValue);