2012-02-25 46 views
5

文件我有一些問題,當我在WinRT中訪問文件有些異常,當訪問在WinRT中

問題1:

var file = await StorageFile.GetFileFromPathAsync(filePath); 

有時GetFileFromPathAsync將拋出一個「RPC服務器不可用」異常。

問題2:

MusicProperties musicProp = await file.Properties.GetMusicPropertiesAsync(); 

有時它會拋出異常:

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)). 

問題3:

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

有時它會引發異常:

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)). 

這些例外不會一直拋出,但有時會拋出。爲什麼?

回答

2

這是線程引發的問題,它是一個COM錯誤信息。並非完全意外,WinRT是基於COM的。錯誤消息說的是在一個線程上創建的接口指針正在另一個線程上使用,而未被封送。

這是您在編寫原始COM代碼時通常必須自己做的事情。底層的COM幫助函數是名爲CoMarshalInterThreadInterfaceInStream()的歡快名字。但是,您明確使用託管代碼。 CLR的職責是在必要時編組指針。它一直可靠地一直回到.NET 1.0版本,我從來沒有見過這種情況。

這非常強烈地暗示了C#await/async管道或CLR的WinRT投影中的一個錯誤。特別是因爲它是虛假的,這種編組錯誤應該是一致的。沒有什麼可以解決你自己。使用connect.microsoft.com門戶報告錯誤,他們需要一個小的repro項目來演示問題。

現在唯一可用的解決方法是仔細控制應用中的線程。通過僅在您創建它的同一個線程上使用該對象來避免此不幸事件。這不完全是你會逃避錯誤的保證。否則,當您嘗試使用pre-beta代碼時,您可能會產生頭痛。