2016-04-24 1 views
0

Ich erstelle eine kleine universelle Windows-Anwendung. Ich möchte MapControl verwenden, um einige aus dem Internet heruntergeladene Daten darzustellen. Diese Daten werden jede Minute aktualisiert und ich möchte die MapIcons-Positionen jedes Mal aktualisieren, wenn dies geschieht. So ... Nach dem Laden einer Karte, ich einen Timer erstellen, der alle 60 Sekunden ausgeführt wird und die Daten mit HttpWebRequest herunterlädt, analysiert dann empfangene JSON und aktualisiert dann die Positionen von MapIcons in MapControl angezeigt.MapIcon Erstellung in Timer Callback

Alles sollte gut funktionieren, aber wenn ich neue MapIcon() im Timer-Rückruf habe ich eine Ausnahme:

Eine Ausnahme vom Typ ‚System.Exception‘ in newproject.exe aufgetreten war aber nicht behandelt in Benutzercode

Weitere Informationen: Die Anwendung hat eine Schnittstelle aufgerufen, die für einen anderen Thread marshalled wurde. (Ausnahme von HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Mein Timer Rückruf-Code ist:

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); 
       } 
      } 
     } 
    } 

Antwort

1

Bitte versuchen Sie einen Dispatcher. Sie müssen MapIcon-Objekte auf dem UI-Thread hinzufügen.

private async void MainPage_Loaded(object sender, RoutedEventArgs e) 
    { 
     await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
     { 
      // Your Code 
     }); 
    } 
0

Obwohl Jean-Sébastien Dupuy's answer ist technisch korrekt, eine weitere Option ist HttpClient statt HttpWebRequest zu verwenden, und verwenden Sie das Schlüsselwort await alles automatisch auf dem richtigen Thread läuft zu gewährleisten. (Stellen Sie außerdem sicher, dass Sie eine DispatcherTimer und keine andere Art von Timer verwenden).