Idioma
Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Este artigo aborda tarefas em segundo plano criadas com a API Windows Runtime BackgroundTaskBuilder no Windows.ApplicationModel.Background namespace para apps com identidade de pacote, incluindo UWP e apps de desktop empacotados. Se você estiver criando um novo aplicativo ou migrando um aplicativo existente para o SDK do Aplicativo Windows, consulte Usando tarefas em segundo plano em aplicativos Windows e Estratégia de migração de tarefas em segundo plano.
Saiba como criar e registrar uma tarefa em segundo plano em seu aplicativo com a classe Windows Runtime (WinRT) BackgroundTaskBuilder.
Registrar uma tarefa em segundo plano
Consulte o exemplo BackgroundTask para obter um exemplo completo de registro de uma tarefa em segundo plano em um aplicativo Plataforma Universal do Windows (UWP).
O exemplo a seguir mostra o registro de uma tarefa COM do Win32 que é executada em um temporizador recorrente de 15 minutos.
Para registrar uma tarefa em segundo plano, primeiro você deve criar uma nova instância da classe BackgroundTaskBuilder . A BackgroundTaskBuilder classe é usada para criar e registrar tarefas em segundo plano em seu aplicativo. O exemplo de código a seguir demonstra como criar uma nova instância da BackgroundTaskBuilder classe:
using System;
using Windows.ApplicationModel.Background;
public IBackgroundTaskRegistration RegisterBackgroundTaskWithSystem(IBackgroundTrigger trigger, Guid entryPointClsid, string taskName)
{
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.SetTrigger(trigger);
builder.SetTaskEntryPointClsid(entryPointClsid);
BackgroundTaskRegistration registration;
if (builder.Validate())
{
registration = builder.Register(taskName);
}
else
{
registration = null;
}
return registration;
}
RegisterBackgroundTaskWithSystem(new TimeTrigger(15, false), typeof(TimeTriggeredTask).GUID, typeof(TimeTriggeredTask).Name);
O RegisterBackgroundTaskWithSystem método usa três parâmetros:
-
trigger: o gatilho que iniciará a tarefa em segundo plano. -
entryPointClsid: a ID da classe do ponto de entrada da tarefa em segundo plano. -
taskName: O nome da tarefa em segundo plano.
O método RegisterBackgroundTaskWithSystem cria uma nova instância da classe BackgroundTaskBuilder e define o ID de classe de gatilho e ponto de entrada para a tarefa em segundo plano. Em seguida, o método registra a tarefa em segundo plano com o sistema.
Observação
Esta classe não é ágil, o que significa que você precisa considerar o modelo de threading e o comportamento de marshaling. Para obter mais informações, consulte Threading and Marshaling (C++/CX) e Usando objetos Windows Runtime em um ambiente multithread (.NET).
Processar em espera moderno em uma tarefa em segundo plano
O BackgroundTaskBuilder e as APIs relacionadas já permitem que aplicativos de área de trabalho empacotados executem tarefas em segundo plano. A API agora estende essas APIs para permitir que esses aplicativos executem código em espera moderno. A atualização também adiciona propriedades que podem ser consultadas por um aplicativo para determinar se o sistema restringirá as tarefas em segundo plano do aplicativo em modo de espera moderno para conservar a vida útil da bateria. Isso permite cenários como aplicativos que recebem chamadas VoIP ou outras notificações push do modo de espera moderno.
Observação
"Aplicativos desktop empacotados" nesta seção se refere a aplicativos Win32 que tenham identidade do pacote (ou seja, são aplicativos de ponte desktop ou assinados esparsos) e têm uma função principal (ou wmain) como o ponto de entrada.
O exemplo a seguir mostra como um desenvolvedor de aplicativos pode usar a API BackgroundTaskBuilder para registrar no máximo uma tarefa com o nome da tarefa especificado. O exemplo também mostra como verificar e optar pelo registro de tarefas para serem executadas em modo de espera moderno nas tarefas mais críticas do aplicativo.
// The following namespace is required for BackgroundTaskBuilder APIs.
using Windows.ApplicationModel.Background;
// The following namespace is required for API version checks.
using Windows.Foundation.Metadata;
// The following namespace is used for showing Toast Notifications. This
// namespace requires the Microsoft.Toolkit.Uwp.Notifications NuGet package
// version 7.0 or greater.
using Microsoft.Toolkit.Uwp.Notifications;
// Incoming calls are considered to be critical tasks to the operation of the app.
const string IncomingCallTaskName = "IncomingCallTask";
const string NotificationTaskName = "NotificationTask";
const string PrefetchTaskName = "PrefetchTask";
public static bool IsAllowedInBackground(BackgroundAccessStatus status) {
return ((status != BackgroundAccessStatus.Denied) &&
(status != BackgroundAccessStatus.DeniedBySystemPolicy) &&
(status != BackgroundAccessStatus.DeniedByUser) &&
(status != BackgroundAccessStatus.Unspecified));
}
public async void RegisterTask(IBackgroundTrigger trigger,
Guid entryPointClsid,
string taskName,
bool isRunInStandbyRequested)
{
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.SetTrigger(trigger);
taskBuilder.SetTaskEntryPointClsid(entryPointClsid);
// Only the most critical background work should be allowed to proceed in
// modern standby. Additionally, some platforms may not support modern
// or running background tasks in modern standby at all. Only attempt to
// request modern standby execution if both are true. Requesting network
// is necessary when running in modern standby to handle push notifications.
if (IsRunInStandbyRequested && taskBuilder.IsRunningTaskInStandbySupported)
{
var accessStatus = BackgroundExecutionManager.GetAccessStatusForModernStandby();
if (!IsAllowedInBackground(accessStatus)
{
await BackgroundExecutionManager.RequestAccessKindForModernStandby(
BackgroundAccessRequestKind.AllowedSubjectToSystemPolicy,
"This app wants to receive incoming notifications while your device is asleep");
}
accessStatus = BackgroundExecutionManager.GetAccessStatusForModernStandby();
if (IsAllowedInBackground(accessStatus)
{
taskBuilder.IsRunningTaskInStandbyRequested = true;
taskBuilder.IsNetworkRequested = true;
}
}
// Check that the registration is valid before attempting to register.
if (taskBuilder.IsRegistrationValid)
{
// If a task with the specified name already exists, it is unregistered
// before a new one is registered. Note this API may still fail from
// catastrophic failure (e.g., memory allocation failure).
taskBuilder.Register(taskName);
}
return;
}
RegisterTask(new PushNotificationTrigger(), "{INSERT-YOUR-GUID-HERE}", IncomingCallTaskName, true);
Verificar se as tarefas em segundo plano excederam seu orçamento no Modern Standby
O código de exemplo a seguir mostra como um desenvolvedor de aplicativos pode usar o BackgroundWorkCost.WasApplicationThrottledInStandby e BackgroundWorkCost.ApplicationEnergyUseLevel para monitorar e reagir a fazer com que suas tarefas em segundo plano esgote o orçamento do aplicativo. O desenvolvedor do aplicativo pode reagir reduzindo o trabalho de menor prioridade realizado durante a espera moderna. Observe que isso depende do código do exemplo anterior.
public async void ReduceBackgroundCost()
{
BackgroundTaskRegistration callTask;
BackgroundTaskRegistration notificationTask;
BackgroundTaskRegistration prefetchTask;
// Nothing to do if the app was not or will not be throttled.
if (!BackgroundWorkCost.WasApplicationThrottledInStandby &&
(BackgroundWorkCost.ApplicationEnergyUseLevel != StandbyEnergyUseLevel.OverBudget))
{
return;
}
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
switch (task.Value.Name) {
case IncomingCallTaskName:
callTask = task.Value;
break;
case NotificationTaskName:
notificationTask = task.Value;
break;
case PrefetchTaskName:
prefetchTask = task.Value;
break;
default:
}
}
if (callTask.WasTaskThrottledInStandby)
{
// Unset the throttle flag after acknowledging it so the app can
// react to the same task being throttled again in the future.
task.Value.WasTaskThrottledInStandby = false;
// Notify the user that the notification was missed.
new ToastContentBuilder()
.AddText("You missed a call")
.AddText(task.Value.Name)
.Show();
// Because the incoming calls were not activated, demote less notifications
// tasks so the calls can be delivered promptly in the future.
RegisterTask(notificationTask.Value.Trigger,
typeof(TimeTriggeredTask).GUID,
notificationTask.Value.Name,
false);
}
// Note that if incoming call tasks were throttled in some previous modern
// standby session, the application energy use was over budget for some period.
// Demote unimportant tasks like prefetch work to avoid calls and notifications
// from being throttled.
if (callTask.WasTaskThrottledInStandby) ||
(BackgroundWorkCost.ApplicationEnergyUseLevel == StandbyEnergyUseLevel.OverBudget))
{
RegisterTask(prefetchTask.Value.Trigger,
typeof(TimeTriggeredTask).GUID,
prefetchTask.Value.Name,
false);
}
return;
}
Monitorar tendências de uso de energia da tarefa em segundo plano
Veja a seguir uma atualização incremental de ponta a ponta para o seguinte código de exemplo C++WinRT/C# em GitHub.
O exemplo mostra como você pode usar o BackgroundWorkCost.ApplicationEnergyUseTrend para monitorar como suas tarefas em segundo plano têm a tendência de esgotar seu orçamento. Você também pode impedir que as tarefas em segundo plano mais caras sejam executadas em espera moderna e evitar que outras tarefas sejam executadas assim, caso o aplicativo esteja usando o orçamento rapidamente. Este exemplo depende do código de exemplos anteriores.
public async void ReduceBackgroundCostPreemptively()
{
BackgroundTaskRegistration mostExpensiveTask = null;
// We can't do anything preemptively since the trend isn't known.
if (!BackgroundWorkCost.IsApplicationEnergyUseTrendKnown)
{
return;
}
// The app is not trending towards being over budget, so this method can
// return early.
if ((BackgroundWorkCost.ApplicationEnergyUseTrend != EnergyUseTrend.OverBudget) &&
(BackgroundWorkCost.ApplicationEnergyUseTrend != EnergyUseTrend.OverHalf))
{
return;
}
// The application is going exceeding its budget very quickly. Demote the
// most expensive task that is not the call task before call tasks start being
// throttled.
if (BackgroundWorkCost.ApplicationEnergyUseTrend == EnergyUseTrend.OverBudget)
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if ((task.Value.Name != IncomingCallTaskName) &&
((mostExpensiveTask == null) ||
(mostExpensiveTask.ApplicationEnergyUseTrendContributionPercentage <
task.Value.ApplicationEnergyUseTrendContributionPercentage)))
{
mostExpensiveTask = task.Value;
}
}
}
if (mostExpensiveTask != null)
{
RegisterTask(mostExpensiveTask.Trigger,
typeof(TimeTriggeredTask).GUID,
mostExpensiveTask.Name,
false);
}
// The application is trending toward eventually exceeding its budget. Demote the
// least important prefetch task before calls and notifications are throttled.
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == PrefetchTaskName) {
RegisterTask(task.Value.Trigger,
typeof(TimeTriggeredTask).GUID,
task.Value.Name,
false);
}
}
return;
}
Tarefas em segundo plano e conectividade de rede
Se sua tarefa em segundo plano exigir conectividade de rede, esteja ciente das considerações a seguir.
Gatilhos relacionados à rede
- Use um SocketActivityTrigger para ativar a tarefa em segundo plano quando um pacote é recebido e você precisa executar uma tarefa de curta duração. Depois de executar a tarefa, a tarefa em segundo plano deve ser encerrada para economizar energia.
- Use um ControlChannelTrigger para ativar a tarefa em segundo plano quando um pacote é recebido e você precisa executar uma tarefa de longa duração.
Condições e sinalizadores relacionados à rede
- Adicione a condição InternetAvailable (BackgroundTaskBuilder.AddCondition) à tarefa em segundo plano BackgroundTaskBuilder.AddCondition para atrasar o disparo da tarefa em segundo plano até que a pilha de rede esteja em execução. Essa condição economiza energia porque a tarefa em segundo plano não será executada até que o acesso à rede esteja disponível. Essa condição não fornece ativação em tempo real.
- Independentemente do gatilho usado, defina IsNetworkRequested em sua tarefa em segundo plano para garantir que a rede permaneça ativa enquanto a tarefa em segundo plano é executada. Isso informa a infraestrutura de tarefas em segundo plano para manter a rede ativa enquanto a tarefa está em execução, mesmo que o dispositivo tenha entrado no modo Connected Standby. Se sua tarefa em segundo plano não usar IsNetworkRequested, sua tarefa em segundo plano não poderá acessar a rede quando estiver no modo De espera conectado.
Conteúdo relacionado
Windows developer