Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Den här artikeln beskriver bakgrundsaktiviteter som skapats med api:et Windows Runtime (WinRT) BackgroundTaskBuilder i Windows. ApplicationModel.Background namnrymd för appar med paketidentitet, inklusive UWP och paketerade skrivbordsappar. Om du skapar en ny app eller migrerar en befintlig app till Windows App SDK kan du läsa Använda bakgrundsaktiviteter i Windows appar och Migreringsstrategi för bakgrundsaktivitet.
Lär dig hur du skapar och registrerar en bakgrundsaktivitet i din app med klassen Windows Runtime (WinRT) BackgroundTaskBuilder.
Registrera en bakgrundsaktivitet
Se exemplet BackgroundTask för ett fullständigt exempel på hur du registrerar en bakgrundsaktivitet i en Universal Windows Platform (UWP) app.
I följande exempel visas registreringen av en Win32 COM-uppgift som körs på en återkommande 15-minuters timer.
Om du vill registrera en bakgrundsaktivitet måste du först skapa en ny instans av klassen BackgroundTaskBuilder . Klassen BackgroundTaskBuilder används för att skapa och registrera bakgrundsuppgifter i din app. Följande kodexempel visar hur du skapar en ny instans av BackgroundTaskBuilder klassen:
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);
Metoden RegisterBackgroundTaskWithSystem tar tre parametrar:
-
trigger: Utlösaren som startar bakgrundsaktiviteten. -
entryPointClsid: Klass-ID för startpunkten för bakgrundsaktiviteten. -
taskName: Namnet på bakgrundsaktiviteten.
Metoden RegisterBackgroundTaskWithSystem skapar en ny instans av BackgroundTaskBuilder klassen och anger utlösaren och startpunktsklassens ID för bakgrundsaktiviteten. Metoden registrerar sedan bakgrundsaktiviteten med systemet.
Anmärkning
Den här klassen är inte agil, vilket innebär att du måste överväga dess trådningsmodell och marshalingbeteende. För mer information, se Threading and Marshaling (C++/CX) och Using Windows Runtime objects in a multithreaded environment (.NET).
Hantera modernt vänteläge i en bakgrundsaktivitet
BackgroundTaskBuilder och relaterade API:er tillåter redan paketerade skrivbordsprogram att köra bakgrundsaktiviteter. API:et utökar nu dessa API:er så att dessa appls kan köra kod i modernt vänteläge. Uppdateringen lägger också till egenskaper som kan förfrågas av en app för att avgöra om systemet stryper bakgrundsaktiviteter för applikationen i modernt vänteläge för att spara batteritid. Detta möjliggör scenarier som appar som tar emot VoIP-samtal eller andra push-meddelanden från modernt vänteläge.
Anmärkning
"Paketerade skrivbordsprogram" i det här avsnittet refererar till Win32-program som har paketidentitet (d.v.s. är Desktop Bridge- eller Sparse Signed Packaged-program) och har en huvudfunktion (eller wmain) som startpunkt.
I följande exempel visas hur en apputvecklare kan använda API:et BackgroundTaskBuilder för att registrera högst en uppgift med det angivna uppgiftsnamnet. Exemplet visar också hur du kontrollerar och väljer att aktivitetsregistreringen ska köras i modernt vänteläge för programmets mest kritiska uppgifter.
// 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);
Kontrollera om bakgrundsaktiviteter har överskridit sin budget i modernt vänteläge
Följande exempelkod visar hur en apputvecklare kan använda BackgroundWorkCost.WasApplicationThrottledInStandby och BackgroundWorkCost.ApplicationEnergyUseLevel för att övervaka och reagera på att deras bakgrundsuppgifter överbelastar appens budget. Apputvecklaren kan reagera genom att minska arbetet med lägre prioritet i modernt vänteläge. Observera att detta förlitar sig på koden från föregående exempel.
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;
}
Övervaka energianvändningstrender för bakgrundsaktiviteter
Följande är en stegvis uppdatering från slutpunkt till slutpunkt till följande C++WinRT/C#-exempelkod på GitHub.
Exemplet visar hur du kan använda BackgroundWorkCost.ApplicationEnergyUseTrend för att övervaka hur dina bakgrundsuppgifter går mot att förbruka sin budget. Du kan också stoppa de mest resurskrävande bakgrundsprocesserna från att köras i modernt vänteläge och hindra bakgrundsprocesser från att köras i vänteläge om deras app förbrukar sin budget för snabbt. Det här exemplet förlitar sig på kod från tidigare exempel.
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;
}
Bakgrundsuppgifter och nätverksanslutning
Om bakgrundsaktiviteten kräver nätverksanslutning bör du vara medveten om följande överväganden.
Nätverksrelaterade utlösare
- Använd en SocketActivityTrigger för att aktivera bakgrundsaktiviteten när ett paket tas emot och du måste utföra en kortvarig uppgift. När du har utfört uppgiften bör bakgrundsaktiviteten avslutas för att spara ström.
- Använd en ControlChannelTrigger för att aktivera bakgrundsaktiviteten när ett paket tas emot och du måste utföra en långlivad uppgift.
Nätverksrelaterade villkor och flaggor
- Lägg till villkoret InternetAvailable (BackgroundTaskBuilder.AddCondition) i bakgrundsaktiviteten för att fördröja utlösandet av bakgrundsaktiviteten tills nätverksstacken körs. Det här villkoret sparar ström eftersom bakgrundsaktiviteten inte körs förrän nätverksåtkomst är tillgänglig. Det här villkoret ger inte aktivering i realtid.
- Oavsett vilken utlösare du använder ställer du in IsNetworkRequested på bakgrundsaktiviteten för att säkerställa att nätverket håller sig uppe medan bakgrundsaktiviteten körs. Detta talar om för infrastrukturen för bakgrundsaktiviteten att hålla nätverket uppe medan aktiviteten körs, även om enheten har gått in i läget Anslutet vänteläge. Om bakgrundsaktiviteten inte använder IsNetworkRequested kommer bakgrundsaktiviteten inte att kunna komma åt nätverket i läget Anslutet vänteläge.
Relaterat innehåll
Windows developer