首页 > 解决方案 > StorageFileQueryResult.GetFilesAsync() 在 UWP 中与 IndexerOption 正确使用

问题描述

我想知道以下是否是错误或充其量是 Windows Search API 的文档不准确StorageFolder

这是一个简单的 UWP 应用程序,它允许用户选择一个文件夹并深入扫描该文件夹以简单地计算文件数量。

如果文件夹在此处放置一段时间,则返回的计数与 Windows 10 的文件资源管理器一致,但如果该文件夹刚刚从笔记本电脑的另一个分区复制到 C 驱动器,则返回的计数不一致。为了弄清楚这个问题,我将一个包含1768个视频和图像文件的文件夹复制到桌面并当场运行该应用程序,这样 Windows 10 就没有时间索引内容。

C#代码(XAML很简单,可以从C#代码中猜到)

    private async void AppBarButton_Click(object sender, RoutedEventArgs e)
    {
        var folderPicker = new FolderPicker
        {
            SuggestedStartLocation = PickerLocationId.Desktop,
            ViewMode = PickerViewMode.Thumbnail

        };

        folderPicker.FileTypeFilter.Add("*");

        _folder = await folderPicker.PickSingleFolderAsync();
        if (_folder != null)
        {
            resultStackPanel.Children.Clear();
            var indexState = await _folder.GetIndexedStateAsync();
            bottomInfoTextBlock.Text = indexState.ToString();
            var queryOptions = new QueryOptions { FolderDepth = FolderDepth.Deep };
            foreach (IndexerOption indexerOption in Enum.GetValues(typeof(IndexerOption)))
            {
                queryOptions.IndexerOption = indexerOption;
                await CountFilesAsync(queryOptions);
            }
        }
    }

    private async Task CountFilesAsync(QueryOptions queryOptions)
    {
        var textBlock = new TextBlock();
        resultStackPanel.Children.Add(textBlock);

        if (!_folder.AreQueryOptionsSupported(queryOptions))
        {
            textBlock.Text = $"Query unsupported for {queryOptions.IndexerOption}";
            return;
        }
        var query = _folder.CreateFileQueryWithOptions(queryOptions);

        textBlock.Text = $"{queryOptions.IndexerOption}: Wait, getting files count ...";
        var numOfFiles = (await query.GetFilesAsync()).Count;
        textBlock.Text = $"{queryOptions.IndexerOption} {numOfFiles}";
    }
}

当我遍历IndexerOption Enum

扫描文件夹结果

我期望的是IndexerOption.UseIndexerWhenAvailable返回的确切计数1768,因为它被记录为

对已编入索引的内容使用系统索引,对未编入索引的内容直接使用文件系统。

我担心的是我想避免使用DoNotUseIndexer Enumvalue 因为我计划从每个存储文件中检索缩略图和额外属性的性能,但这个选项是唯一提供正确计数的选项。

我检查了微软的照片应用程序只加载了一部分内容,即好像它使用了UseIndexerWhenAvailable,但它有能力在我等待 1-2 分钟时自行更新。

因此,我想知道是否:

1)我为用户提供准确结果的唯一解决方案是使用DoNotUseIndexer Enum或者是否可能UseIndexerWhenAvailable或理想情况下OnlyUseIndexerAndOptimizeForIndexedProperties但在 Windows 10 最终索引所有文件以通知我的应用程序时通过某些事件进行跟踪?

2)UseIndexerWhenAvailable实际上在做什么?它似乎与它的描述不一致

谢谢

标签: uwpstoragefile

解决方案


以下允许在文件系统更改时通知应用程序。在调用方法中触发事件

            query.ContentsChanged += Query_ContentsChanged;

   private async void Query_ContentsChanged(IStorageQueryResultBase sender, object args)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            var count = await sender.GetItemCountAsync();
            var textBlock = new TextBlock();
            resultStackPanel.Children.Add(textBlock);
            textBlock.Text = $"Changed {count} {sender.Folder.Name}";
        });
    }

局部变量count可以设置为页面中的属性,例如OneWay绑定到TextBlock.Text带有INotifyPropertyChanged. 这样,该值将随着 Windows 索引所有文件而更新,大约一分钟后,计数达到最终值 1768。此外,删除或添加文件夹中的文件将更新 UI 计数。唯一要注意的是,如果您在某个时候重命名该文件夹。在这种情况下,应用程序将开始计算默认值SuggestedStartLocation,在我的例子中是桌面。因此,检查sender.Folder.Name所选择的实用程序_folder(代码未显示)。


推荐阅读