agolia
agolia

Reputation: 207

Windows Store Apps StorageFolder.GetFilesAsync() causes OOM Exception

I am new to Windows Store App development and I have an app written in C# that attempts to get the size of all files in a specified directory and its sub-directories. The StorageFolder.GetFilesAsync() method works fine for directories with a small number of files, however with directories containing a large number of files it produces an OOM exception on devices with only 2GB of RAM such as many of the RT tablets. Is there a way to go about this that would allow the app to to process the files in smaller chunks rather than building a list of all files (which seems very inefficient) as the code demonstrates below, any help would be appreciated...

StorageFolderQueryResult queryResult = KnownFolders.RemovableDevices.CreateFolderQueryWithOptions(new QueryOptions(CommonFolderQuery.DefaultQuery));

folderList = await queryResult.GetFoldersAsync();
foreach (StorageFolder folder in folderList)
{
    IReadOnlyList<StorageFile> fileList = await folder.GetFilesAsync(CommonFileQuery.DefaultQuery);

    foreach (StorageFile file in fileList)
    {
        BasicProperties properties = await file.GetBasicPropertiesAsync();
        size += properties.Size;
    }
}

Upvotes: 1

Views: 3305

Answers (1)

Nate Diamond
Nate Diamond

Reputation: 5575

Use StorageFolderQueryResult.GetFoldersAsync(uint, uint) along with StorageFolderQueryResult.GetItemCountAsync to query the folders in chunks.

Something like:

StorageFolderQueryResult queryResult = KnownFolders.RemovableDevices.CreateFolderQueryWithOptions(new QueryOptions(CommonFolderQuery.DefaultQuery));

uint numItems = await queryResult.GetItemCountAsync();
uint chunkSize = 50;

for(uint startingIndex = 0; startingIndex < numItems; startingIndex += chunkSize)
{
    var folderList = await queryResult.GetFoldersAsync(startingIndex, chunkSize);
    foreach (StorageFolder folder in folderList)
    {
        IReadOnlyList<StorageFile> fileList = await folder.GetFilesAsync(CommonFileQuery.DefaultQuery);

        foreach (StorageFile file in fileList)
        {
            BasicProperties properties = await file.GetBasicPropertiesAsync();
            size += properties.Size;
        }
    }
}   

You can increase or decrease the chunkSize based on how you want to bound your memory.

Hope this helps. Happy Coding!

Upvotes: 2

Related Questions