Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

some exception when access the file in winrt

I have some problems when I access files in winrt

question 1:

var file = await StorageFile.GetFileFromPathAsync(filePath);

sometimes the GetFileFromPathAsync will throw an "the rpc server is unavailable" exception.

question 2:

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

sometimes it will throws an exception:

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

question 3:

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

sometimes it will throw an exception:

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

These exceptions won't be thrown all the time, but sometimes. Why?

like image 985
troyou Avatar asked Nov 04 '22 05:11

troyou


1 Answers

It is the kind of problem that's induced by threading, it is a COM error message. Not entirely unexpected, WinRT is heavily COM based. What the error message says is that an interface pointer that was created on one thread is being used on another thread without having been marshaled.

This is something that you normally have to do yourself when you write raw COM code. The underlying COM helper function is the joyfully named CoMarshalInterThreadInterfaceInStream(). However, you are clearly using managed code. It is the CLR's job to marshal pointers where necessary. It has done so reliably and consistently all the way back to .NET version 1.0, I've never seen a case where it fumbled.

This very strongly hints to a bug in either the C# await/async plumbing or the CLR's WinRT projection. Especially since it is spurious, this kind of marshaling bug should be consistent. Nothing you can fix yourself. Use the connect.microsoft.com portal to report the bug, they'll need a small repro project that demonstrates the problem.

The only workaround you'll have available right now is to carefully control the threading in your app. Avoid this mishap by only using the object on the same thread you created it. This is not exactly a guarantee that you'll evade the bug. Otherwise the kind of headache you can expect when you try to use pre-beta code.

like image 158
Hans Passant Avatar answered Nov 18 '22 16:11

Hans Passant