-1

This one is hard to explain, so I give you some actual and pseudo code:

try
{
   // If source (a string) points towards a file that is available with 
   // StorageFile.GetFileFromPathAsync(), just open the file that way.
   // If that is not possible, use the path to look up an Access Token
   // and use the file from the StorageFolder gotten via that token.

   StorageFile file = await GetFileFromAccessList(source);

   if (file != null)
   {
      bitmap = new BitmapImage();
      using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
      {
          await bitmap.SetSourceAsync(fileStream);
      }
   }
}
catch (Exception e)
{
   string s = e.Message;
   bitmap = null;
}

with the following method:

    public async Task<StorageFile> GetFileFromAccessList(string path)
    {
        StorageFile result = null;

        if (String.IsNullOrEmpty(path) == false)
            try
            {
                // Try to access to file directly...
                result = await StorageFile.GetFileFromPathAsync(path);

            }
            catch (Exception)
            {
                result = null;
                try
                {
                    // See if the folder this thing is in is in the access list...
                    StorageFolder folder = await GetFolderFromAccessList(Path.GetFullPath(path));

                    // If there is a folder, try that.
                    if (folder != null)
                        result = await folder.GetFileAsync(Path.GetFileName(path));
                }
                catch (Exception)
                {
                    result = null;
                }
            }

        return result;
    }

The resulting bitmap is used in Image.SetSource() as an ImageSource.

Now what kills me: this call works perfectly, fast and rock solid for files stored within the apps folder or KnownFolders. So it works like a charm when I don't need an Access Token. Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token)

However, it breaks if I have to use an access token, just not all the time This code does not break immediately: it breaks when I try to open more than 5-7 source files at the same time. Repeat that: this works if I display 5-7 images. If I try to open more, it freezes the PC. No such problem occurs when I open StorageFiles without tokens.

I can access such files using normal file operations. I can create bitmaps from them, process them, the work. I just cannot make them a source of an XAML Image.

Any thoughts?

J. H.
  • 109
  • 9
  • What actually happens? The code hangs on the `SetSourceAsync` line? Is there any exception? And do you have any insider preview installed (Windows 10 preview, SDK preview)? – Martin Zikmund Feb 27 '18 at 17:27
  • What happens is that the PC freezes indefinitely. No fireworks, just hangs. – J. H. Feb 28 '18 at 17:35

1 Answers1

0

Ah clarity. So it turns out that using the DataContextChanged event to refresh the bitmap through Image.SetSource() is the murder weapon.

The solution: declare a property of type BitmapSource. Bind the Image.Source to that property. Update the property with the loaded bitmap upon Image.Loaded and Image.DataContextChanged. Works stable and fast now in all conditions I was able to test.

J. H.
  • 109
  • 9