在winrt中访问文件时出现一些异常

tro*_*you 5 microsoft-metro windows-8 windows-runtime

我在winrt中访问文件时遇到一些问题

问题1:

var file = await StorageFile.GetFileFromPathAsync(filePath);
Run Code Online (Sandbox Code Playgroud)

有时,GetFileFromPathAsync将抛出"rpc服务器不可用"异常.

问题2:

MusicProperties musicProp = await file.Properties.GetMusicPropertiesAsync();
Run Code Online (Sandbox Code Playgroud)

有时它会引发异常:

Unable to cast COM object of type 'Windows.Storage.FileProperties.MusicProperties' to interface type 'Windows.Storage.FileProperties.IMusicProperties'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{BC8AAB62-66EC-419A-BC5D-CA65A4CB46DA}' failed due to the following error: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)).
Run Code Online (Sandbox Code Playgroud)

问题3:

QueryOptions query = new QueryOptions(CommonFileQuery.OrderByMusicInfo, extensionList);
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(query);
IReadOnlyList<IStorageFile> files = await queryResult.GetFilesAsync();
Run Code Online (Sandbox Code Playgroud)

有时会抛出异常:

Unable to cast COM object of type 'Windows.Storage.StorageFile' to interface type 'Windows.Storage.IStorageFile'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{C7034384-F12E-457A-89DA-69A5F8186D1C}' failed due to the following error: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)).
Run Code Online (Sandbox Code Playgroud)

这些异常不会一直抛出,但有时会抛出.为什么?

Han*_*ant 2

这是由线程引发的问题,是 COM 错误消息。并非完全出乎意料,WinRT 很大程度上基于 COM。该错误消息表示,在一个线程上创建的接口指针正在另一个线程上使用,而尚未进行封送。

这是您在编写原始 COM 代码时通常必须自己完成的事情。底层的 COM 辅助函数是 CoMarshalInterThreadInterfaceInStream(),它的名字很有趣。但是,您显然正在使用托管代码。CLR 的工作是在必要时整理指针。一直到 .NET 1.0 版本,它一直如此可靠且一致地完成,我从未见过它出现故障的情况。

这非常强烈地暗示了 C# 等待/异步管道或 CLR 的 WinRT 投影中的错误。特别是因为它是虚假的,所以这种编组错误应该是一致的。没有什么是你自己能解决的。使用 connect.microsoft.com 门户报告错误,他们需要一个小型重现项目来演示该问题。

您现在唯一可用的解决方法是仔细控制应用程序中的线程。通过仅在创建该对象的同一线程上使用该对象来避免这种不幸。这并不能完全保证您能够避免该错误。否则,当您尝试使用预测试版代码时,您可能会遇到令人头痛的问题。