2016-11-28 60 views
0

我对Windows Phone的8.0 Silverlight应用程序异步方法GetStreetName的Windows Phone 8 - 获得多个街名

string streetname; 

private async Task<string> GetStreetName(int i) 
{ 
    MapAddress address; 
    ReverseGeocodeQuery query = new ReverseGeocodeQuery(); 
    query.GeoCoordinate = Route[i].Item1; 
    query.QueryCompleted += (s, e) => 
    { 
     if (e.Error != null) 
      return; 

     address = e.Result[0].Information.Address; 
     streetname = address.Street; 
}; 
query.QueryAsync(); 
return streetname; 
} 

,我把它使用的await运营商内部的for循环创建:

for (int i = 0; i < Route.Count; i++) 
{ 
     ListBox.Items.Add(await GetStreetName(i)); 
} 

但我总是只能得到第一个加载的geoposition的街道名称,我不知道为什么(我认为await运算符正在等待,直到异步方法完成)。

附加信息:我刚刚看到,在这个简短的代码片段中,街道名称和Route是全局“变量”,这并不是100%清楚,Route是一个元组列表,其中第一个项目是地理坐标。

我该如何解决这个问题?

回答

2

在结果准备就绪之前,您从GetStreetName返回,因此query.QueryAsync();只是开始查询并且不会等待它完成。

最重要的是,您将所有结果写入同一全局streetname。您需要使用TaskCompletionSource

尝试这样:

private async Task<string> GetStreetNameAsync(int i) 
{ 
    var tcs = new TaskCompletionSource<IEnumerable<string>>(); 

    EventHandler<QueryCompletedEventArgs<IList<MapLocation>>> handler = (s, e) => 
     { 
      if (e.Error != null) 
      { 
       tcs.TrySetException(e.Error); 
       return; 
      } 

      if (e.Cancelled) 
      { 
       tcs.TrySetCanceled(); 
       return; 
      } 

      tcs.TrySetResult(e.Result[0].Information.Address.Street); 
     }; 

    var query = new ReverseGeocodeQuery(); 
    query.GeoCoordinate = Route[i].Item1; 

    try 
    { 
     query.QueryCompleted += handler; 

     query.QueryAsync(); 

     return await tcs.Task; 
    } 
    finally 
    { 
     query.QueryCompleted -= handler; 
    } 
}