带线程的CoreAudioApi - InvalidCastException

时间:2012-12-24 10:41:47

标签: c# multithreading com .net

我正在编写一个应用程序来修改另一个应用程序的卷并使用CoreAudioApi dll来执行此操作。以下代码块在主线程上完美运行,但在单独的线程中调用时,会引发InvalidCastException。我扔了一个互斥锁,以防这只是两个线程试图访问相同资源的问题,但似乎并非如此。关于问题可能是什么的任何想法?我很难成为一名新的C#程序员。我读了其他问题,其中建议只有主线程可以访问COM对象,如CoreAudioApi,所以我需要向主线程发送一些消息。如果这是正确的,那么最好的方法是什么?

异常(发生在第一个Math.abs if语句中):

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

代码:

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.

2 个答案:

答案 0 :(得分:2)

您的错误消息告诉您在IMMDevice的某些操作期间出现错误。
根据{{​​3}}规范,IMMDevice只有4种方法:

  • Activate
  • OpenPropertyStore
  • GetId
  • GetState

您提供的代码没有提及这些方法,因此要么您误解了您的错误发生在哪里,要么就是您的应用程序产生的内部错误。

我认为从您的设备获取音量时出现内部错误。

如果sASC.SimpleAudioVolume.MasterVolumedefaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar发生此错误,则由于代码而导致此错误进入后台模式。否则,请为您的例外添加一些代码和堆栈跟踪。

在设备的this方法期间,可能会出现错误代码E_NOINTERFACE的错误。因此,您需要将此方法调用到主线程中以激活设备,然后尝试将其用于后台模式。抱歉,无法提供任何示例代码。

答案 1 :(得分:0)

我的应用抛出此异常。我已经对此收集了一些见识。

  • COM对象需要所有线程才能运行
  • 如果您尝试从另一个线程运行该对象,请确保该线程正在运行
  • 如果您的程序在STAThread上运行,并且正在将此COM对象用于Task或另一个Thread中,则它将引发类似这样的异常。

因此,在将COM对象用于MTAThreadTask时,请确保您的程序在Thread下运行。

希望这会有所帮助。

谢谢。