Руководство по работе с фоновыми задачами

Убедитесь, что ваше приложение отвечает требованиям, необходимым для выполнения фоновых задач.

Руководство по фоновым задачам

Рекомендуем использовать следующее руководство при разработке фоновой задачи и перед публикацией вашего приложения.

Если фоновая задача используется для воспроизведения мультимедиа в фоновом режиме, см. раздел Воспроизведение мультимедиа в фоновом режиме, где приведены сведения об улучшениях в Windows 10 версии 1607, которые значительно упрощают работу.

Фоновые задачи, выполняемые внутри или вне процесса: в Windows 10 версии 1607 появились фоновые задачи, выполняемые внутри процесса, которые позволяют выполнять фоновый код в том же процессе, что и основное приложение. При выборе фоновых задач внутри или вне процесса необходимо учитывать следующие факторы:

Оценка Влияние
Устойчивость Если фоновый процесс выполняется в другом процессе, сбой в фоновом процессе не повлияет на работу приложения переднего плана. Кроме того, фоновую операцию можно завершить (даже из приложения), если время ее выполнения выходит за заданные пределы. Выделение фоновой работы в задачу, отдельную от приложения переднего плана, может быть лучшим выбором, когда не требуется обмениваться данными между процессом переднего плана и фоновым процессом (поскольку отсутствие необходимости во взаимодействии между процессами является одним из основных преимуществ фоновых задач, выполняющихся внутри процесса).
Простота Фоновые задачи, выполняющиеся внутри процесса, не требуют взаимодействия между процессами и проще в разработке.
Доступные триггеры Фоновые задачи внутри процесса не поддерживают следующие триггеры: DeviceUseTrigger, DeviceServicingTrigger и IoTStartupTask.
VoIP Фоновые задачи внутри процесса не поддерживают активации фоновой задачи VoIP в приложении.

Ограничения на количество экземпляров триггера: существуют ограничения на количество экземпляров некоторых триггеров, которые может зарегистрировать приложение. Приложение может зарегистрировать ApplicationTrigger, MediaProcessingTrigger и DeviceUseTrigger только один раз для каждого экземпляра приложения. Если приложение переходит за этот предел, регистрация вызовет исключение.

Квоты ЦП: фоновые задачи ограничены физическим временем использования, которое они получают в зависимости от типа триггера. Большинство триггеров ограничены 30 секундами использования, хотя некоторые могут выполняться до 10 минут для завершения сложных задач. Фоновые задачи должны быть облегченными, чтобы экономить время работы батареи и обеспечивать удобную работу с приложениями переднего плана. Сведения об ограничениях ресурсов для фоновых задач см. в статье Поддержка приложения с помощью фоновых задач.

Управление фоновыми задачами: ваше приложение должно получать список зарегистрированных фоновых задач, регистрировать обработчики выполнения и завершения и обрабатывать эти события соответствующим образом. Классы фоновой задачи должны сообщать о выполнении, отмене и завершении. Подробнее об этом см. в статьях Обработка отмененной фоновой задачи и Отслеживание хода выполнения и завершения фоновых задач.

Использование BackgroundTaskDeferral: если класс вашей фоновой задачи выполняет асинхронный код, обязательно используйте отсрочки. В противном случае фоновая задача может быть преждевременно завершена при возврате метода Run (или метод OnBackgroundActivated в случае внутрипроцессных фоновых задач). Дополнительные сведения см. в разделе Создание и регистрация фоновой задачи вне процесса.

Можно также запросить одну отсрочку и использовать async/await, чтобы завершить асинхронные вызовы метода. Закройте отсрочку после вызовов метода await.

Обновите манифест приложения: Для фоновых задач, выполняемых вне процесса, объявите каждую фоновую задачу в манифесте приложения вместе с типом триггеров, с которыми она используется. В противном случае ваше приложение не сможет зарегистрировать фоновую задачу во время выполнения.

При наличии нескольких фоновых задач определите, следует ли их выполнять в одном хост-процессе или их нужно разделить на разные хост-процессы. Если вы считаете, что сбой в одной фоновой задаче может вывести из строя другие фоновые задачи, поместите их в разных хост-процессах. Используйте запись Группа ресурсов в конструкторе манифеста, чтобы разместить фоновые задачи в различных хост-процессах.

Чтобы настроить группу ресурсов, откройте конструктор Package.appxmanifest, выберите Объявления и добавьте объявление службы приложения:

Настройка группы ресурсов

Дополнительные сведения о настройке группы ресурсов см. в справочнике по схеме приложений.

Фоновые задачи, которые выполняются в том же процессе, что и приложение переднего плана, не требуется объявлять в манифесте приложения. Дополнительные сведения об объявлении в манифесте фоновых задач, которые выполняются вне процесса, см. в разделе Объявление фоновых задач в манифесте приложения.

Подготовка к обновлениям приложений: если ваше приложение будет обновляться, создайте и зарегистрируйте фоновую задачу ServicingComplete (см. SystemTriggerType), чтобы отменить регистрацию фоновых задач для предыдущей версии приложения и зарегистрировать фоновые задачи для новой версии. Это также подходящий момент для выполнения обновлений приложения, которые могут быть необходимы вне контекста выполнения на переднем плане.

Запрос на выполнение фоновых задач:

Важно Начиная с Windows 10 приложения больше не должны находиться на экране блокировки в качестве необходимого условия для выполнения фоновых задач.

Приложения универсальной платформы Windows (UWP) могут выполнять все поддерживаемые типы задач без закрепления на экране блокировки. Однако приложения должны вызывать GetAccessState и проверка, что приложению не запрещено работать в фоновом режиме. Убедитесь, что GetAccessStatus не возвращает одно из запрещенных перечислений BackgroundAccessStatus . Например, этот метод возвращает BackgroundAccessStatus.DeniedByUser , если пользователь явно отказал в разрешениях фоновой задачи для вашего приложения в параметрах устройства.

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

Дополнительные сведения о доступных пользователю настройках фоновых задач и экономии заряда см. в разделе Оптимизация фоновой активности.

Контрольный список для фоновых задач

Относится к фоновым задачам, которые выполняются как внутри, так и вне процесса

  • Сопоставьте вашу фоновую задачу с правильным триггером.
  • Добавьте условия, которые поспособствуют успешному выполнению вашей фоновой задачи.
  • Обработайте выполнение, завершение и отмену фоновой задачи.
  • Повторно зарегистрируйте свои фоновые задачи во время запуска приложения. Это гарантирует их регистрацию во время первого запуска. Это позволяет узнать, отключил ли пользователь возможности фонового выполнения приложения (в случае сбоя регистрации).
  • Проверьте наличие ошибок регистрации фоновых задач. При необходимости попытайтесь зарегистрировать фоновую задачу снова с другими значениями параметров.
  • Если устройству не хватает памяти, фоновые задачи могут быть завершены для всех семейств устройств (за исключением настольных компьютеров). Если исключение "Недостаточно памяти" не отображается или приложение не обрабатывает его, то фоновая задача будет завершена без предупреждения и без вызова события OnCanceled. Это позволяет не прерывать работу пользователя с активным приложением. Ваша фоновая задача должна поддерживать этот сценарий.

Относится только к фоновым задачам вне процесса

  • Создайте фоновую задачу в компоненте среда выполнения Windows.
  • Не отображайте никакие элементы пользовательского интерфейса, кроме уведомлений, плиток и обновлений индикаторов событий из кода фоновой задачи.
  • В методе Run запросите отсрочки для каждого асинхронного вызова метода и закройте их после завершения метода. Можно также использовать одну отсрочку вместе с async/await.
  • Используйте постоянное хранилище для совместного использования данных фоновой задачей и приложением.
  • Объявите каждую фоновую задачу в манифесте приложения вместе с типом триггеров, если он используется с задачей. Убедитесь, что точка входа и типы триггеров указаны правильно.
  • Не указывайте в манифесте элемент Executable за исключением случая, когда используется триггер, который должен выполняться в одном контексте с приложением (например, ControlChannelTrigger).

Относится только к фоновым задачам внутри процесса

  • При отмене задачи убедитесь, что существует обработчик события BackgroundActivated; в противном случае будет прервано выполнение всего процесса.
  • Пишите кратковременные фоновые задачи. Большинство фоновых задач ограничены 30 секундами использования часов.

Чего следует избегать

  • Сведите к минимуму использование межпроцессного взаимодействия через COM или RPC.
  • Процесс, с которым вы пытаетесь связаться, может не находиться в состоянии выполнения, что может привести к зависаю.
  • Значительное количество времени может быть потрачено на взаимодействие между процессами, и будет учитываться время, отведенное на выполнение фоновой задачи.
  • Не используйте взаимодействие с пользователем в фоновых задачах.