Windows Phone 8 - 获取多个街道名称

时间:2016-11-28 15:50:49

标签: silverlight windows-phone-8 async-await maps

我为Windows Phone 8.0 Silverlight App创建了一个异步方法GetStreetName

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

我在for循环中使用await运算符调用它:

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

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

其他信息:我刚刚看到这个简短的片段不是100%清楚,街道名称和路线是全局的&#34;变量&#34;,路线是一个元组列表,其中第一个项目是地理坐标。

如何解决此问题?

1 个答案:

答案 0 :(得分: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;
    }
}