2016-11-28 4 views
0

I für Windows Phone 8.0 Silverlight App ein Asynchron-Methode erstellt GetStreetNameWindows Phone 8 - Erste Mehrere Straßennamen

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

und ich nenne es den await Operator innerhalb einer for-Schleife:

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

aber ich bekomme immer nur den Straßennamen der ersten geladenen Geoposition zurück und ich habe keine Ahnung warum (ich dachte, der Warteoperator wartet, bis die Async-Methode beendet ist).

Zusätzliche Informationen: Ich habe gerade gesehen, dass dies an diesem kurzen Ausschnitt nicht 100% klar ist, Straßenname und Route sind globale "Variablen", Route ist eine Tupelliste, wobei der erste Gegenstand eine Geo-Koordinate ist.

Wie kann ich dieses Problem beheben?

Antwort

2

Sie kehren von GetStreetName zurück, bevor die Ergebnisse bereit sind. Becayse query.QueryAsync(); startet die Abfrage und wartet nicht auf ihre Vollständigkeit.

Darüber hinaus schreiben Sie alle Ergebnisse auf die gleiche globale streetname.

Sie müssen eine TaskCompletionSource verwenden.

versuchen, etwas wie folgt aus:

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