Search code examples
c#vb.netuwpenumeratestoragefile

UWP Enumerate Folders with 10,000 files while creating a subfolder


I'm a fairly experienced developer, but this has me stumped in UWP - I'll keep it simple.

Let's say I want to go through all photos in the pictures folder, watermark them, and save the watermarked version in a sub folder of pictures (eg. pictures\watermarked)

Sound easy?

Try 1: Using GetFilesAsync (incl. GetItemsAsync, GetFoldersAsync) - This method goes through every file, giving me the StorageFile objects I need.

There are 2 problems with this approach:

  1. I can't show a progress bar until I've scanned every file and that's painfully slow in UWP.

  2. The Runtime Broker will consume all memory if I keep any reference to the StorageFile object (so enumerate and enumerate again to get a progress is seriously slow, think 1,000 times slower than Win32)

Try 2: Using Queries - This method involves using Windows.System.Search & Queries to return a list of pointers (ish) to all the files. I can then use StorageFolderQueryResult to get each StorageFile on the fly and release immediately so that the Runtime Broker behaves. This is very fast as it uses the Windows Index system, really, really fast.

The problem is that the query system is fairly stupid, as soon I create the subfolder "Watermarked Photos", the storagefiles returned by the Query (which did not exist when it was queried) start to contain files from the Watermarked folder. It appears that the Query is actually just a number of files, not a static list of the actual files, so the results are arbitrary based on any files added/removed after the query was invoked within it's scope.

Anyone with thoughts on how to do this?


Solution

  • RESOLVED - It's not possible using the index system. I created my own Query class. It uses the GetItemsAsync method of folders, the number of objects here won't kill the RuntimeBroker, I store the Path in a string list. containing the paths of all files and sub folders. I can then use GetFileFromPathAsync to instantiate and destroy StorageItems as needed. The RuntimeBroker is okay with that, although it's not the best performance it does give me custom file/folder filtering. Happy to elaborate if anyone needs more info.