2016-03-20 9 views
1

Hintergrund:WP8.1 RT: Datenbindung (remote) Bilder verlangsamen App

Ich bin auf einer WP8.1/WP10 mobile app arbeiten, die mit einem lokalen Gerät arbeitet ich hier habe. Dieses lokale Gerät dient JSON und Bildern über eine ASP.NET Web APi. Meine App führt Internetanrufe aus, um Informationen abzurufen und die Informationen für den Benutzer anzuzeigen. Ganz einfache Einrichtung.

Mein Prozess funktioniert wie folgt: Benutzer startet die App. Die App findet den 'Webservice' im Netzwerk mit UPNP. Wenn dies der Fall ist, tauscht es ein Token aus und wir können den Web-Service aufrufen. Ich nehme eine Liste von Objekten, die einen Titel, Untertitel und ein Bild enthalten. Bilder uri sind wie:

192.168.1.x:8080/getImage/?uri=someremoteimageurihere. 

Mein Gerät diese Bilder herunterladen und bringt sie zu der App (Ich brauche es auf diese Art und Weise dieses Gerät hat für einige andere Anwendungen zu arbeiten).

Um die Benutzeroberfläche flüssig zu halten, verwende ich Virtualisierung auf der Liste, die ich zeige, und der Benutzer kann ohne Verzögerung durch die Liste scrollen. So weit, ist es gut. Es gibt nur ein Problem:

Mein Problem

Mein Problem mit den Bildern in meiner Listview-Vorlage ist. Während die Benutzeroberfläche reagiert, lädt das Telefon ständig Bilder herunter, insbesondere wenn ein Benutzer von Element # 300 zu Element # 1 scrollt. Sie werden sehen, wie die Bilder nacheinander von # 299 bis # 1 heruntergeladen werden. Das Problem ist, dass der Benutzer # 1 in der Liste anzeigt, und es dauert etwa eine Minute, bis alle Bilder heruntergeladen sind, es geht von # 299 zu # 1.

Ich frage mich, wie ich mehr Kontrolle über das Laden dieser Bilder bekommen kann. Während es diese Bilder herunterlädt, scheint meine App wenig Zeit für "andere" Aufgaben zu haben, z. Alle anderen Aufrufe der Web-API scheinen zu warten, bis die Bilder auf dem Bildschirm geladen sind (ohne den ui-Thread zu sperren!). Wenn ich also zu einem Einstellungs-Flyout navigiere, werden die Einstellungen erst geladen, nachdem der Stapel von Bildern geladen wurde.

Gibt es eine Möglichkeit für mich, diese Bilder auf einen einzelnen Hintergrund Thread zu laden? Die Verzögerung für den Endbenutzer ist akzeptabel, solange die Bindung der Bilder nicht Vorrang vor anderen Bildern erhält.

Diese Frage ist nicht zu:

  • den UI-Thread sperren, während der Arbeit
  • Hilfe mit Bindungsdaten
  • Caching-Strategien für Ihre Erkenntnisse

Dank zu tun!

+0

Hat WebAPI Sie die Bilder in der Größe dienen das Telefon sie angezeigt werden muss oder es wird ihnen Ändern der Größe? Die Größenänderung ist langsam. –

+0

Nein, tut es nicht, und ich habe keine Möglichkeit, dies zu tun (dieser Teil ist ein Dritter). Also ja, alle Bilder werden im Handumdrehen verkleinert, was nicht hilft. –

Antwort

0

Sie können versuchen, direkt an Ihre heruntergeladenen Bilder (als ImageSource-Ressource) zu binden, anstatt den Server Uri zu verwenden: Sie haben also die Kontrolle, diese Bilder in Ihrem eigenen Code im Hintergrund herunterzuladen und verfügbar zu machen in Ihrem ViewModel als eine Sammlung von Bildern.

können Sie diesen Code versuchen:

public async void GetImage(Uri url) 
{ 
    HttpClient client = new HttpClient(); 
    HttpResponseMessage response = await client.GetAsync(url); 
    byte[] img = response.Content.ReadAsByteArray(); 
    InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream(); 

    DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)); 
    writer.WriteBytes(img); 

    await writer.StoreAsync(); 

    BitmapImage bi = new BitmapImage(); 
    bi.SetSource(randomAccessStream); 

    image1.Source = bi; 
} 

Bitte markieren Sie als beantwortet, ob das hilft :)

+0

Ich habe das versucht, das ist jedoch keine Lösung für mein Problem. Das Problem, das ich habe, ist, dass, wenn Sie von # 1 in der Listenansicht zu # 300 scrollen, wird jedes Bild von 1-300 heruntergeladen, während ich nur diejenigen auf dem Bildschirm herunterladen müssen. Ihre "getimage" -Methode ist nur eine andere Möglichkeit, die Bildquelle einzustellen, was nicht mein tatsächliches Problem ist :). –

+0

Welche Art von Virtualisierung verwenden Sie für Ihre Listenansicht? Inkrementeller oder Direktzugriff? –

1

Würde die Phasing-Funktion fix Sie ausgeben? Phasing ist eine Funktion von {x: Bind}, die mit von ListViewBase abgeleiteten Steuerelementen arbeitet und die Elementvorlage für die Datenbindung inkrementell verarbeitet. Beim Rendern von Listenelementen rendert ListViewBase eine einzelne Phase für alle Elemente in der Ansicht, bevor sie in die nächste Phase übergeht. Die Rendering-Arbeit wird in zeitlich gestaffelten Stapeln durchgeführt, so dass beim Durchlaufen der Liste die erforderliche Arbeit neu bewertet werden kann und nicht für Elemente ausgeführt wird, die nicht mehr sichtbar sind. https://msdn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attribute

1

Sie sollten Zufallsdatenzugriff Datenvirtualisierung auf Listenansicht versuchen:

Random Access Datenvirtualisierung Laden von einem beliebigen Punkt in dem Datensatz erlaubt. Ein ListView, das die Datenvirtualisierung mit wahlfreiem Zugriff verwendet, um eine Sammlung von einer Million Elementen anzuzeigen, kann die Elemente 100.000 - 100.050 laden. Wenn der Benutzer dann an den Anfang der Liste wechselt, lädt das Steuerelement die Elemente 1 bis 50. Der Daumen der Bildlaufleiste zeigt immer an, dass das ListView eine Million Elemente enthält. Die Position des Bildlaufleistenbalkens bezieht sich auf die Position der sichtbaren Elemente im gesamten Datensatz der Sammlung. Diese Art der Datenvirtualisierung kann die Speicheranforderungen und Ladezeiten für die Sammlung erheblich reduzieren. Um es zu aktivieren, müssen Sie eine Datenquellenklasse schreiben, die Daten bei Bedarf abruft, einen lokalen Cache verwaltet und diese Schnittstellen implementiert.

https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/listview-and-gridview-data-optimization#random-access-data-virtualization

+0

Könnten Sie bitte als gelöst markieren? –