en / de
Expertisen
Methoden
Dienstleistungen
Referenzen
Jobs & Karriere
Firma
Technologie-Trends TechCast WebCast TechBlog News Events Academy

WP8: Creating BitmapImages on a background thread

When trying to create a BitmapImage on a background thread an exception is raised indicating to you, the developer, that you may only create a BitmapImage on the UI thread. I recently had the problem where I wanted to download a few images on a background thread and then push the collection to the UI thread once all was ready to be presented to the user. After the first round of swearing why this was raising an exception I saw that there was more then one way how one could set the source of a BitmapImage. One is to assign a stream to the image, which could be a memory stream that takes represents a byte array.

var bitmapImage = new BitmapImage();
bitmapImage.SetSource(new MemoryStream(imageDataBlock));

Downloading a byte array can be done with the HttpClient (only one Nuget package install away) and using its GetByteArrayAsync method. The code bellow downloads multiple images sequentially and adds them to a list of byte arrays.

var httpClient = new HttpClient();
var imageDataBlocks = new List();

foreach (var uri in uris)
{
    imageDataBlocks.Add(await httpClient.GetByteArrayAsync(uri));
}

return imageDataBlocks;

This allows us to download the images on a background thread which we can kick off by using Task.Run(() => DownloadImage(uris)) and then await it which in return enables us to use the resulting list of byte arrays on the UI thread and set them to be the sources of the newly created BitmapImages. Bellow you can see an example implementation demonstrating the download running in a background thread and then creating the BitmapImages on the UI thread.

public class ImageDownloadService
{
    public async Task> DownloadImagesAsync(IEnumerable uris)
    {
        if (uris == null) throw new ArgumentNullException("uris");

        var imageDataBlocks = await Task.Run(() => DownloadImage(uris));

        var images = new List();

        foreach (var imageDataBlock in imageDataBlocks)
        {
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(new MemoryStream(imageDataBlock));
            images.Add(bitmapImage);
        }

        return images;
    }

    private async Task> DownloadImage(IEnumerable uris)
    {
        var httpClient = new HttpClient();
        var imageDataBlocks = new List();

        foreach (var uri in uris)
        {
            imageDataBlocks.Add(await httpClient.GetByteArrayAsync(uri));
        }

        return imageDataBlocks;
    }
}

You can use the same approach when developing for Windows 8, though putting this example into a Portable Class Library is a bit more tricky as BitmapImages are not supported in a PCL.

 

HTH

Kommentare

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Newsletter - aktuelle Angebote, exklusive Tipps und spannende Neuigkeiten

 Jetzt anmelden
NACH OBEN
Zur Webcast Übersicht