计算路由时“无效的跨线程访问” - Windows phone 8

时间:2013-09-06 10:55:41

标签: c# multithreading map windows-phone

我正试图在地图上显示路线,但我得到了这个例外。我无法弄清楚为什么。 这是我的代码隐藏:

public partial class map_new : PhoneApplicationPage
{
    public GeoCoordinate destination;
    public GeoCoordinate myPosition;
    public Geolocator myGeolocator;
    List<GeoCoordinate> waypoints = new List<GeoCoordinate>();
    public RouteQuery routeQuery;


    public map_new()
    {
        InitializeComponent();
        destination = new GeoCoordinate(41.909859, 12.461792);
        ShowDestinationLocationOnTheMap();

        myGeolocator = new Geolocator();
        myGeolocator.DesiredAccuracy = PositionAccuracy.High;
        myGeolocator.MovementThreshold = 20; // The units are meters.
        myGeolocator.StatusChanged+=geolocator_StatusChanged;


    }

    private async Task update_position() 
    {
        Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();
        Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
        myPosition = CoordinateConverter.ConvertGeocoordinate(myGeocoordinate);
        Dispatcher.BeginInvoke(() =>
        {
            this.myMap.Center = myPosition;
            this.myMap.ZoomLevel = 16;
        });
        //update_route();
    }

    private async void update_route()
    {
        await update_position();
        RouteQuery routeQuery = new RouteQuery();
        waypoints.Add(myPosition);
        waypoints.Add(destination);
        routeQuery.Waypoints = waypoints;
        routeQuery.QueryCompleted += routeQuery_QueryCompleted;
        routeQuery.QueryAsync();
    }

    void routeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
    {
        if (e.Error == null)
        {
            Route MyRoute = e.Result;
            MapRoute MyMapRoute = new MapRoute(MyRoute);
            myMap.AddRoute(MyMapRoute);
            routeQuery.Dispose();
        }
    }

    void geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
    {
        string status = "";

        switch (args.Status)
        {

            case PositionStatus.Ready:
                // the location service is generating geopositions as specified by the tracking parameters
                status = "ready";
                update_route();
                break;

    }

我认为错误是update_route()不等待update_position()完​​成,但我不知道如何设置update_route()等待。 任何想法?

编辑:在应用KooKiz和Stephen解决方案后,错误位于此行:

RouteQuery routeQuery = new RouteQuery();

2 个答案:

答案 0 :(得分:3)

尝试从后台线程更新UI时,通常会发生“无效的跨线程访问”。在您的情况下,我相信当您尝试更新myMap控件时。

要从UI线程更新控件,您可以使用Dispatcher.BeginInvoke方法:

private async void update_position() 
{
    Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();
    Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
    myPosition = CoordinateConverter.ConvertGeocoordinate(myGeocoordinate);
    Dispatcher.BeginInvoke(() =>
    {
            this.myMap.Center = myPosition;
            this.myMap.ZoomLevel = 16;
    });
    //update_route();
}

编辑:显然,还需要在UI线程上实例化RouteQuery对象。然后我建议在UI上调用整个update_route方法:

        case PositionStatus.Ready:
            // the location service is generating geopositions as specified by the tracking parameters
            status = "ready";
            Dispatcher.BeginInvoke(() => update_route());
            break;

(然后从Dispatcher.BeginInvoke方法中移除update_position

答案 1 :(得分:0)

你应该避免async void。相反,请使用async Task,这样您就可以await返回Taskasync void只应用于事件处理程序。

我的博客上有introduction to async,您可能会觉得有帮助。