1


I am developing a WP 8.1 app, which contains a ListView. In each ListView items there are some text and a picture. The pictures come from a Http GET request, which I have to bind to the xaml. I have got a solution for it earlier, but I have some performance problem with it. The ListView can contain same picture multiple times, so the GetImage task is called multiple times for the the same picture as well. On a WiFi connection it is not a big problem, but with poor connection it is.
The other thing what I would like to implement is the image caching. I don't know where is the best place to store pictures while the app is running. I should store approximately 10-40 pieces pictures, and the image sizes are between 3 and 20 KB. Due to these images are not necessary after closing the application, I think I can store them in the memory, not in the storage folder.
So, what I want: download every images at once and store them while the app is running.

Here is the code what I use to download images:

public class WebPathToImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (value == null) return null;
            return new TaskCompletionNotifier<BitmapImage>(GetImage((string)value));
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        { throw new NotImplementedException(); }

        private async Task<BitmapImage> GetImage(string emailaddress)
        {
            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            Uri uri = new Uri((string)localSettings.Values["Server"] + "Image/Downloadavatar?EmailAddress=" + emailaddress + "&Size=NORMAL");

            HttpClient webCLient = new HttpClient();
            IInputStream responseStream = await webCLient.GetInputStreamAsync(uri);
            MemoryStream memoryStream = new MemoryStream();
            Stream stream = responseStream.AsStreamForRead();
            await stream.CopyToAsync(memoryStream);
            memoryStream.Position = 0;
            BitmapImage bitmap = new BitmapImage();
            await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
            return bitmap;
    }
}
Speederer
  • 371
  • 5
  • 14

1 Answers1

2

Well I asked a similar question on regards of how to work with caching data downloading and performing them in parallel. Take a look at the answer here: Task caching when performing Tasks in parallel with WhenAll

So in short your GetImage should go in a list that holds the tasks instead of the result.

Community
  • 1
  • 1
Depechie
  • 6,102
  • 24
  • 46
  • Thanks, it works perfectly! All images are downloaded only once. Do you have any idea to store downloaded images while app is running? – Speederer Dec 31 '14 at 11:04
  • Okay, sorry! I know already. :) The images will be stored in the ConcurrentDictionary. – Speederer Dec 31 '14 at 11:09
  • You could offload them to disk if needed... depends on how often they change. For example if it are always the same images, day after day, than do store them on disk and check that first before hitting the web url – Depechie Dec 31 '14 at 12:34
  • There is a good image caching control available in the Q42 lib - take a look at it here https://github.com/Q42/Q42.WinRT – Depechie Dec 31 '14 at 12:37
  • I have seen it earlier, but I think it is better to store images in memory only, not in local storage. Because they are not large, and they may be changed sometimes. So I think your first solution is the best for me. It will turn out soon, after I will try to use the images on other pages. Thanks again. :) – Speederer Dec 31 '14 at 13:39