UWP应用重复导航时调用QueryOptions获取视频库数据引发COMException
解决UWP导航回页面时QueryOptions抛出E_FAIL COM异常的问题
我之前也碰到过类似的UWP文件查询坑,结合你的场景来看,这个E_FAIL的COM异常大概率和查询对象没妥善释放或者页面导航时的资源管理混乱有关,下面给你几个针对性的解决思路:
1. 务必正确释放QueryOptions相关对象
当你导航离开页面时,如果没手动释放查询相关的资源,再次创建新查询时很容易因为资源冲突触发异常。建议在页面的Unloaded事件或者ViewModel的清理逻辑里,主动释放查询实例:
private StorageFileQueryResult _fileQueryResult; public async Task FillFolders() { // 先清理旧的查询对象,避免资源残留 if (_fileQueryResult != null) { _fileQueryResult.Dispose(); _fileQueryResult = null; } var options = new QueryOptions(CommonFileQuery.OrderByDate, new[] { ".mp4", ".avi" }) { IndexerOption = IndexerOption.UseIndexerWhenAvailable, FolderDepth = FolderDepth.Deep }; _fileQueryResult = KnownFolders.VideoLibrary.CreateFileQueryWithOptions(options); var files = await _fileQueryResult.GetFilesAsync(); // 你的后续数据处理逻辑 } // 在页面卸载或者ViewModel销毁时调用 public void CleanupQueryResources() { _fileQueryResult?.Dispose(); }
2. 导航回页面时重置查询状态
有时候导航回页面时,ViewModel可能没被正确重置,导致复用了已经失效的查询实例。可以在页面的OnNavigatedTo事件里,强制重置查询相关的状态,确保每次进入页面都用全新的查询对象:
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // 重置ViewModel的查询状态 ViewModel.ResetQueryState(); // 重新执行数据加载 _ = ViewModel.FillFolders(); }
ViewModel里的重置方法:
public void ResetQueryState() { _fileQueryResult?.Dispose(); _fileQueryResult = null; // 清空之前的文件夹列表,避免旧数据干扰 Folders.Clear(); }
3. 提前检查文件夹访问权限
虽然首次加载没问题,但导航回来时可能遇到系统权限临时变化的情况(比如权限会话过期)。可以在执行查询前先确认访问权限:
public async Task FillFolders() { var accessStatus = await KnownFolders.VideoLibrary.RequestAccessAsync(); if (accessStatus != StorageAccessStatus.Allowed) { // 这里可以给用户提示权限不足,比如弹个对话框 return; } // 继续执行查询逻辑 }
4. 避免异步方法的错误调用方式
一定要确保FillFolders是被正确异步调用的,别用.Wait()或者.Result这种阻塞同步上下文的写法,很容易导致资源死锁:
// 正确的调用方式 await ViewModel.FillFolders(); // 错误的调用方式(会引发各种异常) ViewModel.FillFolders().Wait();
这些方案核心都是围绕查询对象的生命周期管理来解决问题,应该能搞定你导航回页面时的E_FAIL异常。
内容的提问来源于stack exchange,提问作者Muhammad Touseef
相关产品推荐
相关产品推荐

