WASAPI предотвращает автоматическую приостановку Windows?

Плакат первый раз, будьте нежны ;-)

Я пишу аудиоприложение (на С++), которое работает как служба Windows, использует WASAPI для отбора семплов из линии в разъеме и выполняет некоторую обработку.

Что-то, что я заметил, это то, что когда мое приложение «записывает», Windows не будет автоматически приостанавливаться или переходить в спящий режим.

Я зарегистрировался для получения уведомлений о событиях питания, и если я сам нажму кнопку приостановки, моя служба получит соответствующие события питания и обработает их нормально. Если я оставлю систему в приостановке самостоятельно, события питания никогда не будут получены.

Если я удалю биты кода, где я ссылаюсь на WASAPI, события питания будут получены как обычно как при ручной, так и при автоматической приостановке. Таким образом, похоже, что в использовании WASAPI есть что-то, что говорит Windows игнорировать автоматический таймер приостановки.

Может ли кто-нибудь помочь объяснить это поведение, и могу ли я что-нибудь сделать, чтобы остановить его? Я не хочу, чтобы мое приложение было одним из тех, которые плохо себя ведут и не позволяют системам приостанавливаться.


person Community    schedule 13.03.2009    source источник


Ответы (4)


Большое спасибо Ларри за то, что он подтвердил, что такое поведение является преднамеренным, а не тем, что я делаю что-то глупое.

Чтобы обойти эту проблему, я использовал Win32 CallNtPowerInformation() API для получения системного таймера простоя:

SYSTEM_POWER_INFORMATION spi = {0};
NTSTATUS status = CallNtPowerInformation(SystemPowerInformation, NULL, 0, 
                                         &spi, sizeof(spi));

if (NT_SUCCESS(status) && (spi.TimeRemaining==0))
{
    // should have gone to sleep
}

Участник spi.TimeRemaining ведет обратный отсчет (в секундах) от времени, указанного пользователем в панели управления, например. «Система переходит в режим ожидания через 1 час» и сбрасывается всякий раз, когда загрузка ЦП (в процентах) превышает spi.MaxIdlenessAllowed.

Если spi.TimeRemaining когда-нибудь достигнет нуля, система должна перейти в спящий режим, поэтому я закрываю все свои дескрипторы WASAPI и позволяю ей это делать.

person snowcrash09    schedule 09.04.2009

К сожалению, нет механизма, позволяющего делать то, что вы хотите — открытие аудиопотока предотвращает переходы состояния питания, как и открытие файла по сети и многие другие вещи.

Это функция аудиодрайвера (portcls.sys), а не WASAPI, и это не новое поведение для Vista — я полагаю, что XP и Win2K имели схожее поведение (хотя переходы состояния питания в Vista гораздо надежнее, чем в XP). и Win2K, поэтому пользователи больше зависят от них).

В Windows 7 вы можете использовать «powercfg -requests», чтобы узнать, не препятствуют ли какие-либо части системы переходу машины в спящий режим. Дополнительную информацию об этом можно найти здесь

person ReinstateMonica Larry Osterman    schedule 17.03.2009
comment
Я не знал о ключе -requests. Большое спасибо! Большой поклонник здесь. ;) - person macbirdie; 12.05.2009

Я считаю, что в API управления питанием есть функция, которая позволяет приложению сообщать ОС, что оно не хочет, чтобы система переходила в режим энергосбережения в течение некоторого времени (я думаю, что это функция типа включения/выключения). Если что-то в WASAPI вызывает этот метод, вы ничего не сможете сделать. Это имело бы смысл с поведением аппаратной кнопки, поскольку служба управления питанием не обязана выполнять запрос приложения в зависимости от того, как активируется режим питания.

Насчет обхода - не знаю. Одна вещь, которую я мог бы попробовать, — прочитать информацию о тайм-ауте энергосбережения из API управления питанием, а затем приостановить запись, если система приближается к порогу энергосбережения; Хотя я понятия не имею, насколько это будет тяжело. Удачи. :)

person Nick    schedule 13.03.2009

Одна вещь, которую я мог бы попробовать, — прочитать информацию о тайм-ауте энергосбережения из API управления питанием, а затем приостановить запись, если система приближается к порогу энергосбережения;

Хорошая идея, но довольно сложная, я думаю. Тайм-аут энергосбережения должен быть доступен для чтения с помощью API управления питанием, но вам также необходимо знать текущее состояние простоя пользовательского ввода, которое невозможно прочитать из службы Windows.

person Community    schedule 14.03.2009