[英]MapIcon creation in Timer callback
I'm creating a small universal windows application. 我正在创建一个小的通用Windows应用程序。 I'd like to use MapControl to present some data downloaded from the Internet.
我想使用MapControl呈现一些从Internet下载的数据。 This data refreshes every minute and I want to update MapIcons positions everytime that it happens.
该数据每分钟刷新一次,我希望每次发生时都更新MapIcons位置。 So... After loading a map, I create a Timer that runs every 60 seconds and downloads the data using HttpWebRequest, then parses received JSON and then updates the positions of MapIcons displayed in MapControl.
所以...加载地图后,我创建一个Timer,每60秒运行一次,并使用HttpWebRequest下载数据,然后解析接收到的JSON,然后更新MapControl中显示的MapIcons的位置。
Everything should work fine, however when I call new MapIcon() in Timer callback I have an exception: 一切都应该正常工作,但是当我在Timer回调中调用new MapIcon()时,我有一个异常:
An exception of type 'System.Exception' occurred in newproject.exe but was not handled in user code
newproject.exe中发生类型'System.Exception'的异常,但未在用户代码中处理
Additional information: The application called an interface that was marshalled for a different thread.
附加信息:该应用程序称为接口,该接口被编组用于其他线程。 (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
(来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))
My Timer callback code is: 我的Timer回调代码是:
private async void OnTimerTick(Object stateInfo)
{
var TramDataList = await Loader.LoadData();
updateMarkers(TramDataList);
}
private void updateMarkers(List<TramData> tramList)
{
lock (TramMarkerDict)
{
foreach (var tramData in tramList)
{
if (!TramDataDict.ContainsKey(tramData.Id))
{
TramDataDict.Remove(tramData.Id);
TramMarkerDict.Remove(tramData.Id);
}
}
foreach (var tramData in tramList)
{
TramData tmp = null;
var exists = TramDataDict.TryGetValue(tramData.Id, out tmp);
if (exists)
tmp.update(tramData);
else
TramDataDict.Add(tramData.Id, tramData);
}
foreach (var tramData in TramDataDict.Values)
{
MapIcon mapIcon = null;
var geopoint = new Windows.Devices.Geolocation.Geopoint(
new Windows.Devices.Geolocation.BasicGeoposition { Latitude = tramData.Lat, Longitude = tramData.Lng });
var exists = TramMarkerDict.TryGetValue(tramData.Id, out mapIcon);
if (exists)
mapIcon.Location = geopoint;
else
{
mapIcon = new MapIcon { Location = geopoint, Title = tramData.FirstLine, NormalizedAnchorPoint = new Point(0.5, 1) };
TramMarkerDict.Add(tramData.Id, mapIcon);
}
}
}
}
Please try using a Dispatcher. 请尝试使用分派器。 You need to add MapIcon objects on the UI Thread.
您需要在UI线程上添加MapIcon对象。
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Your Code
});
}
Although Jean-Sébastien Dupuy's answer is technically correct, another option is to use HttpClient
instead of HttpWebRequest
and use the await
keyword to ensure everything automatically runs on the correct thread. 尽管Jean-SébastienDupuy的回答在技术上是正确的,但另一个选择是使用
HttpClient
而不是HttpWebRequest
并使用await
关键字来确保所有内容都自动在正确的线程上运行。 (Also make sure you're using a DispatcherTimer
and not some other kind of timer). (还要确保您使用的是
DispatcherTimer
而不是其他某种计时器)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.