CoreAudioApi with threading - InvalidCastException

2019-07-21 11:27发布

问题:

I'm writing an application to modify the volume of another application and using the CoreAudioApi dll to do so. The following block of code works perfectly on the main thread, but when called in a separate thread, an InvalidCastException is raised. I threw in a Mutex in case this was just an issue of two threads trying to access the same resource, but that doesn't appear to be the case. Any ideas as to what the problem might be? I'm stumped as a new C# programmer. I read other questions where its suggested that only the main thread has access to COM objects such as CoreAudioApi, so I need to send some kind of message to the main thread. If this is correct, what is the best way to do this?

Exception (occurs on the first Math.abs if statement):

Unable to cast COM object of type 'System.__ComObject' to interface type 'CoreAudioApi.Interfaces.IMMDevice'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{D666063F-1587-4E43-81F1-B948E807363F}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

Code:

muteSoundMutex.WaitOne();
AudioSessionControl sASC = sInfo.getSAudioSession();
if (Math.Abs(sASC.SimpleAudioVolume.MasterVolume -
      (0.05f / defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar)) < 0.0001 
    && savedVol > 0)
{
   ... // other code here. all mutexes are released correctly.

回答1:

Your error message tells about casting error during some operation with IMMDevice.
According this spec, IMMDevice has only 4 methods:

  • Activate
  • OpenPropertyStore
  • GetId
  • GetState

The code you've provided has no mention of these methods, so either you've misunderstand where is your error occurs, or this is internal error raised up to your application.

I think this is an internal error during getting the Volume from your devices.

If this error occurs into the sASC.SimpleAudioVolume.MasterVolume or defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar, then this error because of code is running into background mode. Otherwise, please add some code and stacktrace for your exception.

Error with error code E_NOINTERFACE can occur during Activate method for the device. So you need call this method into your main thread to activate device, and after that try to use it into your background mode. Can't provide any sample code, sorry.