Philip Colmer
Philip Colmer

Reputation: 1664

Calling await file.OpenAsync appears to hang

I've got a property that is bound in XAML, where the property is supposed to return an image from a file. The property calls the following code:

private async Task<BitmapImage> GetBitmapImageAsync(StorageFile file)
{
   Debug.WriteLine("GetBitmapImageAsync for file {0}", file.Path);
   BitmapImage bitmap = new BitmapImage();
   Debug.WriteLine("... opening the stream");
   using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
   {
      Debug.WriteLine("... setting the source");
      bitmap.SetSource(stream);
      Debug.WriteLine("... and returning");
      return bitmap;
   }
}

The problem I've got is that the code will output the debugging text "... opening the stream" and then it appears to hang.

Can anyone see what I've done wrong or what I can try to fix this?

Upvotes: 0

Views: 3263

Answers (3)

Philip Colmer
Philip Colmer

Reputation: 1664

Just for clarity (having commented on Raubi's answer provided above), here is how I've restructured the code so that it works without having UI objects accessed on the wrong thread.

The calling code looks like this:

BitmapImage bitmap = new BitmapImage();
IRandomAccessStream stream = GetBitmapStreamAsync(file).Result;
bitmap.SetSource(stream);
return bitmap;

and the code for GetBitmapStreamAsync is this:

private async Task<IRandomAccessStream> GetBitmapStreamAsync(StorageFile file)
{
   Debug.WriteLine("GetBitmapStreamAsync for file {0}", file.Path);
   IRandomAccessStream stream = await file.OpenReadAsync().AsTask().ConfigureAwait(false);
   return stream;
}

A couple of notes:

  1. The reason why I've moved the creation of the BitmapImage up to the calling code, rather than keeping it in the original GetBitmapImageAsync, is because when you use ConfigureAwait, the code then executes on a different thread and an exception then gets raised.

  2. The reason why the calling code goes GetBitmapStreamAsync(file).Result rather than using await is because this code is in a Property, which you cannot use async with.

Upvotes: 0

Manuel Rauber
Manuel Rauber

Reputation: 1392

I had a similiar problem: WinRT: Loading static data with GetFileFromApplicationUriAsync()

Please look at the answer from Alexander.

Upvotes: 2

fsimonazzi
fsimonazzi

Reputation: 3013

Is the property waiting on the task? If so, you have a synchronization context issue.

Upvotes: 0

Related Questions