-2

我有两种方法:

private async Task<GeoCoordinate> CenterMapOnMyLocation()
    {
        Geolocator myGeolocator = new Geolocator();
        Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();          
        Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
        GeoCoordinate myGeoCoordinate =
            ConvertGeocoordinate(myGeocoordinate);

        MapCenter = myGeoCoordinate;
        if (MyLocation.Latitude == 0 && MyLocation.Longitude == 0)
        {
            MyLocation = MapCenter;
        }

        return myGeoCoordinate;
    }

private void GetClosestLocations(GeoCoordinate myLocation)
    {
        var locations = new ObservableCollection<PushPinModel>
                    {
                        new PushPinModel
                            {
                                Location = new GeoCoordinate(51.569593, 10.103504),
                                LocationName = "1"
                            },
                        new PushPinModel
                            {
                                Location = new GeoCoordinate(-45.569593, 1.103504),
                                LocationName = "2"
                            },
                        new PushPinModel
                            {
                                Location = new GeoCoordinate(0, 0),
                                LocationName = "3"
                            }
                    };
        foreach (var location in locations)
        {
            location.DistanceToMyLocation = HaversineDistance(myLocation, location.Location);
        }

        Treks = new ObservableCollection<PushPinModel>(locations.OrderBy(l => l.DistanceToMyLocation).Take(2).ToList());
    }

在构造函数中我有这样的东西:

public NearbyControlViewModel()
    {
        var test = CenterMapOnMyLocation();
        GetClosestLocations(test);
    }

现在,我的问题是,当在构造函数中调用第二个方法时,“test”变量还没有初始化……因为它是异步的。我想要做的是等待它被初始化,然后调用第二种方法。如果我从异步方法调用我的第二个方法,我会得到一个异常: InvalidOperationException - 集合处于不可写模式。“Treks”值绑定到 MapItemsControl。所以我猜想关于线程的问题。

4

3 回答 3

2

您需要使用异步初始化。我在关于建筑的博客文章async中给出了一些不同的解决方案。

请注意,异步代码会迫使您拥有更好的 UI 设计。即,您必须为您的 UI 设计某种“在地图居中之前”状态。UI 最初将在该状态下启动,然后当(异步)初始化完成时,更新 UI。

于 2013-05-10T13:10:47.137 回答
1

如果不是构造函数:

public async Task SomeMethod()
{
    var test = await CenterMapOnMyLocation();
    GetClosestLocations(test);
}

但是 - 与构造函数?也许根本不这样做。试图在构造函数中等待可能是致命的——尤其是在某些同步上下文中——这可能会立即死锁。

考虑让它在构造函数之后开始。

于 2013-05-10T12:12:57.390 回答
0

您可以test.Wait();在调用 GetClosestLocation 之前添加一个;毕竟,您从 CenterMapOnMyLocation 获得了一个任务。(编辑:但确实,Marc 是对的,等待是邪恶的。您可能应该重构以在构造函数之外调用异步代码。)

于 2013-05-10T12:17:43.603 回答