uwp - 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
Enum
value 因为我计划从每个存储文件中检索缩略图和额外属性的性能,但这个选项是唯一提供正确计数的选项。
我检查了微软的照片应用程序只加载了一部分内容,即好像它使用了UseIndexerWhenAvailable
,但它有能力在我等待 1-2 分钟时自行更新。
因此,我想知道是否:
1)我为用户提供准确结果的唯一解决方案是使用DoNotUseIndexer
Enum
或者是否可能UseIndexerWhenAvailable
或理想情况下OnlyUseIndexerAndOptimizeForIndexedProperties
但在 Windows 10 最终索引所有文件以通知我的应用程序时通过某些事件进行跟踪?
2)UseIndexerWhenAvailable
实际上在做什么?它似乎与它的描述不一致
谢谢
解决方案
以下允许在文件系统更改时通知应用程序。在调用方法中触发事件
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
(代码未显示)。
推荐阅读
- python - Python:解压字典时为什么不需要 2 个变量?
- ruby-on-rails - Shrine 中未定义的方法“图像”
- css - 单击时更改的带有 css 的动画
- python - 如何创建自定义异常?此异常不起作用
- r - 如何遍历for循环中的参数
- javascript - javascript:针对元素数组查找元素字符串的出现。出现返回 0
- laravel - 如何在 Cpanel 中为实时服务器安装 gRPC 扩展
- c# - 在 Entity Framework Core 中使用动态过滤器
- node.js - [React-Native]:找不到与 @types/react-test-renderer@16.13.1 匹配的版本
- tcl - Tcl:从 exec bash 获取标准输出