我正在创建一个小型通用Windows应用程序。我想使用MapControl来呈现从互联网下载的一些数据。这些数据每分钟刷新一次,我想每次发生时更新 MapIcon 的位置。所以。。。加载地图后,我创建了一个每 60 秒运行一次的计时器,并使用 HttpWebRequest 下载数据,然后解析收到的 JSON,然后更新 MapControl 中显示的 MapIcon 的位置。
一切都应该正常工作,但是当我在计时器回调中调用新的 MapIcon() 时,我有一个例外:
newproject 中发生了类型为"System.Exception"的异常.exe但未在用户代码中处理
其他信息:应用程序调用了为不同线程封送的接口。(HRESULT的例外:0x8001010E(RPC_E_WRONG_THREAD))
我的计时器回调代码是:
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);
}
}
}
}
请尝试使用调度程序。您需要在 UI 线程上添加 MapIcon 对象。
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Your Code
});
}
尽管Jean-Sébastien Dupuy的答案在技术上是正确的,但另一种选择是使用HttpClient
而不是HttpWebRequest
并使用await
关键字来确保所有内容在正确的线程上自动运行。(还要确保您使用的是DispatcherTimer
而不是其他类型的计时器)。