CreateQueryWithOptions 导致系统互操作 Com 异常
CreateQueryWithOptions causes system interop Com exception
好的,所以我有一个简单的 uwp 应用程序,我正在尝试从 KnownFolders.VideoLibrary 获取数据并使其更快,我正在使用 indexing 与 QueryOptions。奇怪的是,在第一次加载页面时我没有收到任何错误,但是当我尝试深入另一个文件夹并再次导航到同一页面时,我得到了这个 Com Exception
Error is of type System.Runtime.InteropServices.COMException
Error HRESULT E_FAIL has been returned from a call to a COM component
我的 ViewModel 中的 FillFolders 方法**
private async Task FillUpFolders()
{
uint index = 0, stepSize = 5;
//on the first load of the LibraryPage I dont get any exception
//but on the 2nd load, I get exception on the line below.
var VideoQuery = FileHelper.GetVideoFoldersQuery(MainFolder, 200);
IReadOnlyList<StorageFolder> folders = await VideoQuery.GetFoldersAsync(index, stepSize);
index += 5;
while (folders.Count != 0)
{
var folderTask = VideoQuery.GetFoldersAsync(index, stepSize).AsTask();
foreach (StorageFolder folder in folders)
{
var vv = new Folder
{
MyStorageFolder = folder,
Title = folder.DisplayName,
Thumbnail = new BitmapImage(new Uri("ms-appx:///Assets/FolderIcon.png")),
MyStretch = Windows.UI.Xaml.Media.Stretch.Uniform
};
Source.Add(vv);
}
folders = await folderTask;
index += 5;
}
}
视频文件查询方法
internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
{
if (videoFolderOptions is null)
{
videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery)
{
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties//check sort order later
};
videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
}
return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
}
I am providing my project on a github repo so anyone can easily reproduce the problem and easily can analyze it.
https://github.com/touseefbsb/UWPStorageFolderBug
StackTrace
" at Windows.Storage.StorageFolder.CreateFolderQueryWithOptions(QueryOptions queryOptions)\r\n at Fluent_Video_Player.Helpers.FileHelper.GetVideoFoldersQuery(StorageFolder Folder, UInt32 thumbnailRequestedSize)\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__11.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__9.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.Views.LibraryPage.d__5.MoveNext()"
重现步骤
- 克隆存储库
- 在VS 2017中打开解决方案
- 运行 应用
- 从左侧导航菜单转到图书馆页面(注意这里没有错误)
- 单击任何文件夹以深入了解它
- 现在你会得到这个异常。
Note : I tried to do ConfigureAwait(false) with Fill() method on LibraryPage.xaml.cs and FillUpFolders() and FillUpFiles() methods within the viewmodel this lead to Marshall thread which I was not able to solve even after using Dispather helper
你能去掉这个选项吗
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties
来自函数 GetVideoFoldersQuery,因此看起来像这样
internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
{
if (videoFolderOptions is null)
{
videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery);
videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
}
return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
}
对于这个版本,我发现它不会崩溃并出现与以前相同的错误。
我确实在函数 GetDisplayForFile 中遇到了 InvalidCastException,但我认为这是完全不同的问题。
编辑
我将以下测试代码块插入到您代码中的 OnNavigateTo 函数中:
var folder = KnownFolders.VideosLibrary;
// Define two different QueryOptions
var qo_1 = new QueryOptions(CommonFolderQuery.DefaultQuery);
var qo_2 = new QueryOptions(CommonFolderQuery.DefaultQuery)
{
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties
};
// Query folder and then query the files and subfolders
// using the first QueryOptions qo_1
var fq_1 = folder.CreateFolderQueryWithOptions ( qo_1 ) ;
var fo_1 = await fq_1.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_1 )
{
var f_1 = subfold.CreateFileQueryWithOptions ( qo_1 ) ;
var sf_1 = subfold.CreateFolderQueryWithOptions ( qo_1 ) ;
}
// Query folder and then query the files and subfolders
// using the first QueryOptions qo_2
var fq_2 = folder.CreateFolderQueryWithOptions ( qo_2 ) ;
var fo_2 = await fq_2.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_2 )
{
var f_2 = subfold.CreateFileQueryWithOptions ( qo_2 ) ;
var sf_2 = subfold.CreateFolderQueryWithOptions ( qo_2 ) ;
}
它定义了两个不同的 QueryOption 对象,然后对每个对象执行二级查询。
第一个工作正常。
第二个在第二级查询时崩溃。
我认为这是一个错误,您应该向 Microsoft 报告。您可能会在 Microsoft 论坛中获得更多帮助。
好的,所以我有一个简单的 uwp 应用程序,我正在尝试从 KnownFolders.VideoLibrary 获取数据并使其更快,我正在使用 indexing 与 QueryOptions。奇怪的是,在第一次加载页面时我没有收到任何错误,但是当我尝试深入另一个文件夹并再次导航到同一页面时,我得到了这个 Com Exception
Error is of type System.Runtime.InteropServices.COMException
Error HRESULT E_FAIL has been returned from a call to a COM component
我的 ViewModel 中的 FillFolders 方法**
private async Task FillUpFolders()
{
uint index = 0, stepSize = 5;
//on the first load of the LibraryPage I dont get any exception
//but on the 2nd load, I get exception on the line below.
var VideoQuery = FileHelper.GetVideoFoldersQuery(MainFolder, 200);
IReadOnlyList<StorageFolder> folders = await VideoQuery.GetFoldersAsync(index, stepSize);
index += 5;
while (folders.Count != 0)
{
var folderTask = VideoQuery.GetFoldersAsync(index, stepSize).AsTask();
foreach (StorageFolder folder in folders)
{
var vv = new Folder
{
MyStorageFolder = folder,
Title = folder.DisplayName,
Thumbnail = new BitmapImage(new Uri("ms-appx:///Assets/FolderIcon.png")),
MyStretch = Windows.UI.Xaml.Media.Stretch.Uniform
};
Source.Add(vv);
}
folders = await folderTask;
index += 5;
}
}
视频文件查询方法
internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
{
if (videoFolderOptions is null)
{
videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery)
{
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties//check sort order later
};
videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
}
return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
}
I am providing my project on a github repo so anyone can easily reproduce the problem and easily can analyze it.
https://github.com/touseefbsb/UWPStorageFolderBug
StackTrace
" at Windows.Storage.StorageFolder.CreateFolderQueryWithOptions(QueryOptions queryOptions)\r\n at Fluent_Video_Player.Helpers.FileHelper.GetVideoFoldersQuery(StorageFolder Folder, UInt32 thumbnailRequestedSize)\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__11.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__9.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.Views.LibraryPage.d__5.MoveNext()"
重现步骤
- 克隆存储库
- 在VS 2017中打开解决方案
- 运行 应用
- 从左侧导航菜单转到图书馆页面(注意这里没有错误)
- 单击任何文件夹以深入了解它
- 现在你会得到这个异常。
Note : I tried to do ConfigureAwait(false) with Fill() method on LibraryPage.xaml.cs and FillUpFolders() and FillUpFiles() methods within the viewmodel this lead to Marshall thread which I was not able to solve even after using Dispather helper
你能去掉这个选项吗
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties
来自函数 GetVideoFoldersQuery,因此看起来像这样
internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
{
if (videoFolderOptions is null)
{
videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery);
videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
}
return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
}
对于这个版本,我发现它不会崩溃并出现与以前相同的错误。
我确实在函数 GetDisplayForFile 中遇到了 InvalidCastException,但我认为这是完全不同的问题。
编辑
我将以下测试代码块插入到您代码中的 OnNavigateTo 函数中:
var folder = KnownFolders.VideosLibrary;
// Define two different QueryOptions
var qo_1 = new QueryOptions(CommonFolderQuery.DefaultQuery);
var qo_2 = new QueryOptions(CommonFolderQuery.DefaultQuery)
{
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties
};
// Query folder and then query the files and subfolders
// using the first QueryOptions qo_1
var fq_1 = folder.CreateFolderQueryWithOptions ( qo_1 ) ;
var fo_1 = await fq_1.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_1 )
{
var f_1 = subfold.CreateFileQueryWithOptions ( qo_1 ) ;
var sf_1 = subfold.CreateFolderQueryWithOptions ( qo_1 ) ;
}
// Query folder and then query the files and subfolders
// using the first QueryOptions qo_2
var fq_2 = folder.CreateFolderQueryWithOptions ( qo_2 ) ;
var fo_2 = await fq_2.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_2 )
{
var f_2 = subfold.CreateFileQueryWithOptions ( qo_2 ) ;
var sf_2 = subfold.CreateFolderQueryWithOptions ( qo_2 ) ;
}
它定义了两个不同的 QueryOption 对象,然后对每个对象执行二级查询。
第一个工作正常。
第二个在第二级查询时崩溃。
我认为这是一个错误,您应该向 Microsoft 报告。您可能会在 Microsoft 论坛中获得更多帮助。