【问题标题】:Waiting for async operation to complete等待异步操作完成
【发布时间】:2013-03-28 01:16:59
【问题描述】:

我有一个关于异步方法如何在 c# 上工作的问题。我试图让 convertAddressToCoordinate 方法将 myLocation 变量设置为 GeoCoordinate。但是,甚至在设置 myLocation 值之前调用 compareDistance 方法。在调用 compareDistance() 之前,如何确保 myLocation 值不为空?

public GeoCoordinate myLocation = null;

public void returnClosestCurrent(string address)
 {

     convertAddressToCoordinate(address);
     compareDistance(myLocation);

 }

 public void convertAddressToCoordinate(string add)
 {
    WebClient wc = new WebClient();
     wc.DownloadStringCompleted += wc_DownloadStringCompleted;
     wc.DownloadStringAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false"));


 }

 void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
 {

    XDocument xdoc = XDocument.Parse(e.Result, LoadOptions.None);

     var data = from query in xdoc.Descendants("location")
                 select new Location
                 {
                     lat = (string)query.Element("lat"),
                     lng = (string)query.Element("lng")
                 };

     GeoCoordinate destinationGeo = new GeoCoordinate(Convert.ToDouble(data.ElementAt(0).lat), Convert.ToDouble(data.ElementAt(0).lng));

     myLocation = destinationGeo;


 }

【问题讨论】:

    标签: c# windows windows-phone-7 windows-phone-8


    【解决方案1】:

    你可以使用 await 关键字来获取异步任务的值

    http://msdn.microsoft.com/en-us/library/vstudio/hh156528.aspx

    【讨论】:

    • 我应该将 await 关键字放在代码中的什么位置? DownloadStringAsync() 没有返回类型。
    • 我认为更好的方法是在downloadstring事件中移动compareDistance方法
    【解决方案2】:

    查看您的代码,在我看来 compareDistance(myLocation); 应该只在 wc_DownloadStringCompleted 方法的末尾调用。

    修改后,一切正常。

    【讨论】:

      【解决方案3】:

      你会想awaitwc.DownloadStringAsync

      public async Task returnClosestCurrent(string address)
      {
          await convertAddressToCoordinate(address)
                    .ContinueWith(t => compareDistance(myLocation));
      }
      
      public async Task convertAddressToCoordinate(string add)
      {
          WebClient wc = new WebClient();
          wc.DownloadStringCompleted += wc_DownloadStringCompleted;
          await wc.DownloadStringAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false"));
      }
      

      带有async/await的模式是代码倾向于将所有内容都变成async/await

      可以重构为使用WebClient.DownloadStringTaskAsync

      public async Task ReturnClosestCurrent(string address)
      {
          await convertAddressToCoordinate(address)
                  .ContinueWith(t => compareDistance(t.Result));
      }
      
      public async Task<GeoCoordinate> ConvertAddressToCoordinate(string add)
      {
          WebClient wc = new WebClient();
          wc.DownloadStringCompleted += wc_DownloadStringCompleted;
          var content = await wc.DownloadStringTaskAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false"));
      
          return ParseContent(content);
      }
      
      private GeoCoordinate ParseContent(string content)
      {
          XDocument xdoc = XDocument.Parse(content, LoadOptions.None);
      
          var data = from query in xdoc.Descendants("location")
                   select new Location
                   {
                       lat = (string)query.Element("lat"),
                       lng = (string)query.Element("lng")
                   };
      
          GeoCoordinate destinationGeo = new GeoCoordinate(Convert.ToDouble(data.ElementAt(0).lat), Convert.ToDouble(data.ElementAt(0).lng));
      
          return destinationGeo;
      }
      

      【讨论】:

      • 显然 Windows Phone 8 不存在 DownloadStringTaskAsync!
      猜你喜欢
      • 1970-01-01
      • 2017-02-15
      • 2013-06-09
      • 2013-08-10
      • 2016-10-24
      • 2020-10-04
      • 2019-05-31
      • 2021-04-16
      • 1970-01-01
      相关资源
      最近更新 更多