c# - 带线程的 CoreAudioApi - InvalidCastException

标签 c# multithreading com .net

我正在编写一个应用程序来修改另一个应用程序的音量,并使用 CoreAudioApi dll 来执行此操作。以下代码块在主线程上运行良好,但在单独的线程中调用时,会引发 InvalidCastException。我加入了一个 Mutex,以防这只是两个线程试图访问同一资源的问题,但事实并非如此。关于问题可能是什么的任何想法?作为一名新的 C# 程序员,我感到很困惑。我阅读了其他问题,其中建议只有主线程才能访问 COM 对象,例如 CoreAudioApi,因此我需要向主线程发送某种消息。如果这是正确的,那么最好的方法是什么?

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

无法将类型为“System.__ComObject”的 COM 对象转换为接口(interface)类型“CoreAudioApi.Interfaces.IMMDevice”。此操作失败,因为 IID 为“{D666063F-1587-4E43-81F1-B948E807363F}”的接口(interface)的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(interface)(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.

最佳答案

您的错误消息告诉您在使用 IMMDevice 进行某些操作时发生了转换错误。
根据this规范,IMMDevice 只有 4 个方法:

  • 激活
  • OpenPropertyStore
  • GetId
  • 获取状态

您提供的代码没有提及这些方法,因此您可能误解了错误发生的位置,或者这是您的应用程序引发的内部错误。

我认为这是从您的设备获取 Volume 时的内部错误。

如果此错误发生在 sASC.SimpleAudioVolume.MasterVolumedefaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar 中,则此错误是因为代码正在运行进入后台模式。否则,请为您的异常添加一些代码和堆栈跟踪。

错误代码为 E_NOINTERFACE 的错误可能会在 Activate 期间发生设备的方法。所以你需要在你的主线程中调用这个方法来激活设备,然后尝试在你的后台模式中使用它。无法提供任何示例代码,抱歉。

关于c# - 带线程的 CoreAudioApi - InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14020232/

相关文章:

c# - 没有在服务中实现接口(interface)成员

c# - Observable.FromAsync+Repeat+TakeWhile 的组合创建无限循环

c++ - QThread在c++中的基本使用

java - JVM线程调度算法是什么?

visual-studio-2012 - ATL COM DLL 寄存器错误 0x80070716

c# - Excel Interop SaveAs() 因大量电子表格数据而挂起

c# - 将字典转换为匿名对象

python : efficiency concerns in parallel async calls to fetch data from web services

python - 自动化 Excel 从 Python 获取 "TypeError: ' unicode' 对象不可调用“在 Range.Address 上

c++ - Direct Show graph - 如何获取当前的 fps?