await bitmapImage.SetSourceAsync(randomAccessStream); hangs and kills Xaml app.

Gavin Williams 761 Reputation points
2020-03-25T09:33:12.36+00:00

Related to: strange-fileloadexceptions.html ( I edited the linked post because this turned out to be unrelated, just an issue with my usage)

When I call SetSourceAsync on a BitmapImage, it never completes and the Xaml app hangs.

Here's a capture of the random access stream feeding into the call. It looks valid.

5901-annotation-2020-03-25-204118.jpg

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,306 Reputation points
    2020-03-25T12:09:55.843+00:00

    Hi,
    your problem is the use of Task<T> and return type. Try following demo.

    XAML

    <Page
        x:Class="App1.Page04"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App04"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
      <Page.DataContext>
        <local:ViewModel/>
      </Page.DataContext>
      <Grid>
        <Image Source="{Binding Picture}"/>
      </Grid>
    </Page>
    

    And ViewModel:

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Threading.Tasks;
    using Windows.ApplicationModel;
    using Windows.Storage;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Media.Imaging;
    
    namespace App04
    {
      public class ViewModel : INotifyPropertyChanged
      {
        public ViewModel() => GetPicture();
    
        public ImageSource Picture { get; set; }
        private async void GetPicture()
        {
          string filePath = "Assets\\DwarfPortrait.png";
          StorageFile file = await Package.Current.InstalledLocation.GetFileAsync(filePath);
          Picture = await GetImageSourceFromStorageFile(file);
          OnPropertyChanged(nameof(Picture));
        }
    
        private static async Task<ImageSource> GetImageSourceFromStorageFile(StorageFile sf)
        {
          using (var randomAccessStream = await sf.OpenAsync(FileAccessMode.Read))
          {
            var result = new BitmapImage();
            await result.SetSourceAsync(randomAccessStream);
            return result;
          }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        internal void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
      }
    }
    
    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful