【问题标题】:Asynchronous call in web serviceWeb 服务中的异步调用
【发布时间】:2012-05-28 23:27:04
【问题描述】:

我正在为我的 wp7 应用程序使用 Web 服务,但我很难确定对服务的异步调用是否返回值。我有一个验证取决于响应(结果)。下面是用于调用 Web 服务的代码 sn-p 以及应该对 UI 进行的适当更改。

private void TLP_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    objevnt.indexChanged(1, lpcountry.SelectedIndex, "depart");
    if(objevnt.CName.Count>0)
    lpcity.ItemsSource = objevnt.GetCityDetails();
}
public void indexChanged(int Travel,int index,string journey)
{
    string slCountry = null;
    switch (Travel)
    {
        case 1:
            slCountry = lstCtryDetails.lstCtrylist[index].countryId.ToString();
            //= "depart";
            travelMode = journey;
            break;
        case 2:
                slCountry = lstCtryDetails.lstCtrylist[index].countryId.ToString();
                travelMode = journey;
                break;
        case 3:
                slCountry = lstCtryDetails.lstCtrylist[index].countryId.ToString();
                travelMode = journey;
                break;
    }

    GetCities = "http://Solutions/mobileservice/Citylist/countrycode/" + slCountry;
    WebClient myClientcity = new WebClient();
    myClientcity.DownloadStringAsync(new Uri(GetCities, UriKind.RelativeOrAbsolute));
    myClientcity.DownloadStringCompleted += new DownloadStringCompletedEventHandler(myClientcity_DownloadStringCompleted);
}

private void myClientcity_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    string _Countries = null;
    if (e.Error == null)
    {
        _Countries = e.Result;
        parseCtry(_Countries);
    }
}

private void parseCtry(string xml)
{
    XDocument myXdoc = XDocument.Load(new StringReader(xml));
    IEnumerable<XElement> lstElm = myXdoc.Descendants("GetCityList");
    lstCtryDetails.lstCitylist.Clear();
    foreach (XElement ele in lstElm.Elements())
    {
        if (ele.Name.ToString() != "Message")
        {
            // Fetch t Details
            if (!ele.IsEmpty && ele.Name.ToString() == "City")
            {
                lstCtryDetails.lstCitylist.Add(new cityList() { CityId = ele.Element("CityCode").Value, CityName = ele.Element("CityName").Value, CityLatitude = ele.Element("Latitude").Value, CityLongitude = ele.Element("Longitude").Value });
                CName.Add(ele.Element("CityName").Value);
                //Countchk = true;
            }
        }
    }

    lsCity = lstCtryDetails.lstCitylist;

    //chkloop = true;
}

public List<cityList> GetCityDetails()
{
    if (lsCity.Count > 0)
        return lsCity;
    return null;
}

现在我需要从 getcitydetails() 方法中获取值列表。但由于异步调用,这是返回 null 。如何获取列表计数,进行适当的验证。提前致谢。

【问题讨论】:

  • 您目前在哪里尝试更新 UI?
  • 我想根据网络服务的响应更新列表选择器。
  • 没有错误但列表总是返回空...计数总是0...
  • parseCtry 被调用,它是否找到任何非空的城市元素?
  • 是的 parseCtry 有一些值,但是条件(count>0)没有得到满足

标签: c# web-services windows-phone-7 asynchronous


【解决方案1】:

您可能在您的WebClient 返回结果之前设置ItemsSource,也没有机会调用parseCtry

如果你搬家:

lpcity.ItemsSource = objevnt.GetCityDetails();

parseCtry 的末尾(即注释//chkloop = true; 所在的位置),然后它将评估为具有正确的计数 - 但您可能会遇到跨线程 UI 访问问题,但您应该能够检查类似(DownloadStringCompleted 开头):

if (Dispatcher.CheckAccess())
    Dispatcher.BeginInvoke(new DownloadStringCompletedEventHandler(myClientcity_DownloadStringCompleted), xml) // put us back on the UI thread if required

您最好将lsCity 的类型更改为ObservableCollection&lt;cityList&gt; 并绑定到它。

【讨论】:

  • 非常感谢 rowl.. 顺便说一句,如果你 cud 解释我如何在 wp7 中使用调度程序和可观察集合。我只使用列表来绑定列表选择器。但我确实听说可观察集合是绑定目的的最佳用途..
  • Rowl,方法 indexchanged() 是我在我的应用程序中使用的一些地方。因此我将它放在一个公共类中并等待返回值进行适当的验证。它可以像你规定的那样使用,但我必须在所有这些页面上都使用它.. 为了可重用性,我需要它来使其精确..
  • 我建议不要在讨论使用 ObservableCollection(及其朋友)的好处时死记硬背,而是阅读 MSDN's article on implementing MVVM on Windows Phone,它会引导您了解 如何.
  • 我问过的第二个问题怎么样。 Rowl,方法 indexchanged() 是我在我的应用程序中使用的一些地方。因此我将它放在一个公共类中并等待返回值进行适当的验证。它可以像你规定的那样使用,但我必须在所有这些页面上都使用它.. 为了可重用性,我需要它来使其精确..
  • 遵循 MVVM 模型也可以回答这个问题——您的页面(视图)可以使用可以共享模型的视图模型——您可以将该逻辑移动到不同的层,并在视图模型和绑定到它们的视图之间共享它。
【解决方案2】:

您是否尝试在执行网络请求之前添加回调?

myClientcity.DownloadStringCompleted += new DownloadStringCompletedEventHandler(myClientcity_DownloadStringCompleted);
myClientcity.DownloadStringAsync(new Uri(GetCities, UriKind.RelativeOrAbsolute));

=== 更新 ===

从你的 cmets 我想我理解这个问题。你想要的是 data bindObservableCollection&lt;T&gt; 到你的 UI 元素 lpCity。例如,如果lpCity 是数据绑定到lsCity(实现ObservableCollection&lt;T&gt;),一旦通过异步Web 请求更新lpCity,UI 元素将自动更新。

我会为你写一个代码框架,我不在我的 Windows PC 上。

【讨论】:

  • 我在事件处理程序之后尝试了异步,但是 Web 服务的响应是异步的,因此对于以下条件 if(objevnt.CName.Count>0) lpcity.ItemsSource = objevnt.GetCityDetails(); else MessageBox.Show("没有可用的城市");即使我从网络服务获取城市列表,也总是重定向到其他部分
猜你喜欢
  • 2023-03-15
  • 2011-09-03
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多