RX 和 Web 服务集合加载 wp7 时出现问题

发布于 2024-11-15 23:14:24 字数 2287 浏览 1 评论 0原文

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

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

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

代码:

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 不同的顺序。

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

卢卡斯

I'm beginner with C# and wp7 platform and I have some problem with good idea to get request from web service.

I made webservice in PHP (nusoap - WSDL) and everything is working fine in "normal" using.
Now I have ObservableCollection saved in IsolatedStorage with I load when Page is open (List of watched stacks exchange). Then I want to refresh data for every item from web service.

I don't know whether this is a good idea.

Code:

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

Like u see I use RX to call method client_GetLastValueCompleted add store result to auxiliary variable (StoredStock). Then refresh List in setList method, but that method is client_GetLastValueCompleted what is not soo good idea, becouse I need to run that method only when all of runned GetLastValueAsync in foreach is completed.
Second problem: becouse of async web service method StoredStock sometime have different order than App.ViewModel.Items .

Any good idea how to do that in right way?
Best regards,

Lukas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光清浅 2024-11-22 23:14:24

您确实混淆了多种调用 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);

You're really mixing up a number of ways to call web services and Rx. You really need to decide on a single way and stick to it.

If you're going to use Rx, then you'll have something like this:

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

You'll have to get the right method call names for your web service client, but the code should roughly be right. Let me know how you go.


I corrected the code above. Should have returned the query inside the Using call rather than assign it to values.


I corrected the call to FromAsyncPattern to use the correct method names and return type from the actual web service reference class sent via email.

It should look like this:

Observable.FromAsyncPattern<string, GetLastValueResponse>
    (ws.BeginGetLastValue, ws.EndGetLastValue);
手心的海 2024-11-22 23:14:24

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

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

If you're a beginner with C#, try to avoid RX for the time being. It is a cool technology, but if you use it without clear understanding of what is going on, it will bring more problems than solve.

Use a simple event, and when each async item arrives, locate and update the correspondent one in the stored list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文