2012-09-05 54 views
7

背景:在Windows Vista及以上,使用擴展Core Audio API(雷Molenkamp研究和Xavier費利克斯)通過訂閱DefaultAudioEndpoint的OnVolumeNotification和設置強制執行的音量音量變化時。CoreAudio的OnVolumeNotification事件訂閱導致explorer.exe的CPU使用率過高

問題:功能成功,但只要訂閱OnVolumeNotification被註冊時,CPU往往在30%-50%取決於你的CPU的功率,以便獲得盯住。在用Process Explorer & Process Monitor進行大量挖掘之後,發現explorer.exe和svchost.exe會被註冊表讀取調用佔用。我不確定哪個註冊表項。我不認爲我會以有害的方式訂閱此活動,因爲我會認真管理訂閱 - 它只會被解僱一次。

從端點執行體積

  1. 退訂OnVolumeNotification
  2. 集終點體積標量屬性(立即生效)
  3. 訂閱端點OnVolumeNotification

基礎Win32方法的邏輯處理參與Core Audio API的是RegisterControlChangeNotifyUnregisterControlChangeNotify。這可能是由於這些問題或事件訂閱的實施引起的嗎?

+1

爲什麼不清楚正在讀取什麼註冊表項? Process Monitor應該爲您提供這些信息。可能有幫助。另外,你是否嘗試調試explorer.exe? – Simon

+0

@Simon我很抱歉沒有注意到你的評論。我無法找到任何特定的按鍵,我對ProcMon並不熟悉。我將爲可能遇到相同問題的用戶發佈解決方法。 – erodewald

回答

0

不是:

  1. 退訂
  2. 變化體積/設置靜音
  3. 重新訂閱

我修改邏輯以在性能基本上使用邏輯與支持字段時管理更新。這並不完美,但它非常貼心,並且不會消耗任何CPU,並且它允許來自滑塊的外部輸入,並且完全支持INPC。

public EndpointVolumeEnforcer() { 
    try { 
    mmDeviceEnumerator = new MMDeviceEnumerator(); 
    mmDevice = mmDeviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia); 
    audioEndpointVolume = mmDevice.AudioEndpointVolume; 
    audioEndpointVolume.OnVolumeNotification += data => { 
     VolumePercent = Convert.ToInt16(data.MasterVolume*100); 
     DeviceIsMuted = data.Muted; 
    }; 
    DesiredVolume = 65; 
    } 
    catch (Exception ex) { 
    // Logging logic here 
    } 
} 

public int DesiredVolume { 
    get { return _desiredVolume; } 
    private set { 
    if (_desiredVolume == value) return; 
    _desiredVolume = value; 
    NotifyOfPropertyChange(); 
    Enforce(_desiredVolume); 
    } 
} 

public int VolumePercent { 
    get { return volumePercent; } 
    private set { 
    if (volumePercent == value) return; 
    volumePercent = value; 
    if (volumePercent != _desiredVolume) { 
     volumePercent = _desiredVolume; 
     Enforce(volumePercent); 
    } 
    } 
} 

public void Enforce(int pct, bool mute = false) { 
    var adjusted = Convert.ToInt16(audioEndpointVolume.MasterVolumeLevelScalar*100); 
    if (adjusted != DesiredVolume) { 
    audioEndpointVolume.MasterVolumeLevelScalar = pct/100f; 
    } 
} 
相關問題