计算路由时的“无效的跨线程访问” - Windows Phone 8
本文关键字:Windows 访问 Phone 路由 无效 计算 线程 | 更新日期: 2023-09-27 18:30:21
>我试图在地图上显示路线,但我得到了这个异常。 我不知道为什么。这是我的代码隐藏:
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();
"无效的跨线程访问"通常在尝试从后台线程更新 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();
}
编辑:显然,RouteQuery对象也需要在UI线程上实例化。然后我建议在 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;
(然后从update_position
方法中删除Dispatcher.BeginInvoke
)
你应该避免async void
。请改用 async Task
,它允许您await
返回的Task
。 async void
只应用于事件处理程序。
我在我的博客上有一个关于async
的介绍,你可能会觉得有帮助。