Anteckning
Å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.
viktiga API:er
Skapa en bakgrundsaktivitetsklass och registrera den för att köras när din app inte är i förgrunden. Det här avsnittet visar hur du skapar och registrerar en bakgrundsaktivitet som körs i en separat process än appens process. Information om hur du utför bakgrundsarbete direkt i förgrundsprogrammet finns i Skapa och registrera en pågående bakgrundsaktivitet.
Anmärkning
Om du använder en bakgrundsaktivitet för att spela upp media i bakgrunden kan du läsa Spela upp media i bakgrunden för information om förbättringar i Windows 10, version 1607, som gör det mycket enklare.
Anmärkning
Om du implementerar en out-of-process-bakgrundsaktivitet i ett C#-skrivbordsprogram med .NET 6 eller senare använder du C#/WinRT-redigeringsstöd för att skapa en Windows Runtime-komponent. Detta gäller för appar som använder Windows App SDK, WinUI 3, WPF eller WinForms. Se Exempel på bakgrundsuppgift för ett exempel.
Skapa klassen Background Task
Du kan köra kod i bakgrunden genom att skriva klasser som implementerar IBackgroundTask--gränssnittet. Den här koden körs när en specifik händelse utlöses med hjälp av till exempel SystemTrigger eller MaintenanceTrigger.
Följande steg visar hur du skriver en ny klass som implementerar IBackgroundTask--gränssnittet.
- Skapa ett nytt projekt för bakgrundsaktiviteter och lägg till det i din lösning. Det gör du genom att högerklicka på lösningsnoden i Solution Explorer och välja Lägg till>Nytt projekt. Välj sedan Windows Runtime Component projekttyp, namnge projektet och klicka på OK.
- Referera till bakgrundsaktivitetsprojektet från ditt UWP-appprojekt (Universal Windows Platform). För en C#- eller C++-app högerklickar du på Referenser i ditt appprojekt och väljer Lägg till ny referens. Under Solutionväljer du Projects och sedan väljer du namnet på ditt bakgrundsaktivitetsprojekt och klickar på Ok.
- I projektet med bakgrundsuppgifter lägger du till en ny klass som implementerar IBackgroundTask--gränssnittet. Metoden IBackgroundTask.Run är en obligatorisk startpunkt som anropas när den angivna händelsen utlöses. den här metoden krävs i varje bakgrundsaktivitet.
Anmärkning
Själva bakgrundsaktivitetsklassen – och alla andra klasser i bakgrundsaktivitetsprojektet – måste vara offentliga klasser som förseglade (eller slutgiltiga).
Följande exempelkod visar en mycket grundläggande startpunkt för en bakgrundsaktivitetsklass.
// ExampleBackgroundTask.cs
using Windows.ApplicationModel.Background;
namespace Tasks
{
public sealed class ExampleBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
}
}
}
// First, add ExampleBackgroundTask.idl, and then build.
// ExampleBackgroundTask.idl
namespace Tasks
{
[default_interface]
runtimeclass ExampleBackgroundTask : Windows.ApplicationModel.Background.IBackgroundTask
{
ExampleBackgroundTask();
}
}
// ExampleBackgroundTask.h
#pragma once
#include "ExampleBackgroundTask.g.h"
namespace winrt::Tasks::implementation
{
struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask>
{
ExampleBackgroundTask() = default;
void Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance);
};
}
namespace winrt::Tasks::factory_implementation
{
struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask, implementation::ExampleBackgroundTask>
{
};
}
// ExampleBackgroundTask.cpp
#include "pch.h"
#include "ExampleBackgroundTask.h"
namespace winrt::Tasks::implementation
{
void ExampleBackgroundTask::Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
{
throw hresult_not_implemented();
}
}
// ExampleBackgroundTask.h
#pragma once
using namespace Windows::ApplicationModel::Background;
namespace Tasks
{
public ref class ExampleBackgroundTask sealed : public IBackgroundTask
{
public:
ExampleBackgroundTask();
virtual void Run(IBackgroundTaskInstance^ taskInstance);
void OnCompleted(
BackgroundTaskRegistration^ task,
BackgroundTaskCompletedEventArgs^ args
);
};
}
// ExampleBackgroundTask.cpp
#include "ExampleBackgroundTask.h"
using namespace Tasks;
void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
}
- Om du kör någon asynkron kod i bakgrundsaktiviteten måste bakgrundsaktiviteten använda en deferral. Om du inte använder en uppskjutning kan bakgrundsprocessen avslutas oväntat om metoden Kör returnerar innan något asynkront arbete har körts.
Begär uppskjutning i metoden Kör innan du anropar den asynkrona metoden. Spara uppskjutningen till en klassdatamedlem så att den kan nås från den asynkrona metoden. Deklarera att fördröjningen är fullgången när den asynkrona koden har körts klart.
Följande exempelkod hämtar uppskjutningen, sparar den och släpper den när den asynkrona koden är klar.
BackgroundTaskDeferral _deferral; // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation
public async void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral();
//
// TODO: Insert code to start one or more asynchronous methods using the
// await keyword, for example:
//
// await ExampleMethodAsync();
//
_deferral.Complete();
}
// ExampleBackgroundTask.h
...
private:
Windows::ApplicationModel::Background::BackgroundTaskDeferral m_deferral{ nullptr };
// ExampleBackgroundTask.cpp
...
Windows::Foundation::IAsyncAction ExampleBackgroundTask::Run(
Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
{
m_deferral = taskInstance.GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.
// TODO: Modify the following line of code to call a real async function.
co_await ExampleCoroutineAsync(); // Run returns at this point, and resumes when ExampleCoroutineAsync completes.
m_deferral.Complete();
}
void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
m_deferral = taskInstance->GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.
//
// TODO: Modify the following line of code to call a real async function.
// Note that the task<void> return type applies only to async
// actions. If you need to call an async operation instead, replace
// task<void> with the correct return type.
//
task<void> myTask(ExampleFunctionAsync());
myTask.then([=]() {
m_deferral->Complete();
});
}
Anmärkning
I C# kan bakgrundsaktivitetens asynkrona metoder anropas med hjälp av nyckelorden async/await. I C++/CX kan ett liknande resultat uppnås med hjälp av en aktivitetskedja.
Mer information om asynkrona mönster finns i Asynkron programmering. Ytterligare exempel på hur du använder uppskjutningar för att förhindra att en bakgrundsaktivitet stoppas tidigt finns i exempel på bakgrundsaktivitet.
Följande steg slutförs i en av appklasserna (till exempel MainPage.xaml.cs).
Anmärkning
Du kan också skapa en funktion som är dedikerad för att registrera bakgrundsaktiviteter – se Registrera en bakgrundsaktivitet. I så fall kan du i stället för att använda nästa tre steg bara konstruera utlösaren och ange den för registreringsfunktionen tillsammans med uppgiftsnamnet, startpunkten för aktiviteten och (eventuellt) ett villkor.
Registrera bakgrundsaktiviteten som ska köras
- Ta reda på om bakgrundsaktiviteten redan har registrerats genom iterering via egenskapen BackgroundTaskRegistration.AllTasks. Det här steget är viktigt. Om din app inte söker efter befintliga registreringar av bakgrundsaktiviteter kan den enkelt registrera aktiviteten flera gånger, vilket orsakar problem med prestanda och maximalt ut aktivitetens tillgängliga CPU-tid innan arbetet kan slutföras.
I följande exempel itereras egenskapen AllTasks och en flaggvariabel anges till true om aktiviteten redan är registrerad.
var taskRegistered = false;
var exampleTaskName = "ExampleBackgroundTask";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
std::wstring exampleTaskName{ L"ExampleBackgroundTask" };
auto allTasks{ Windows::ApplicationModel::Background::BackgroundTaskRegistration::AllTasks() };
bool taskRegistered{ false };
for (auto const& task : allTasks)
{
if (task.Value().Name() == exampleTaskName)
{
taskRegistered = true;
break;
}
}
// The code in the next step goes here.
boolean taskRegistered = false;
Platform::String^ exampleTaskName = "ExampleBackgroundTask";
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
{
auto cur = iter->Current->Value;
if(cur->Name == exampleTaskName)
{
taskRegistered = true;
break;
}
hascur = iter->MoveNext();
}
- Om bakgrundsaktiviteten inte redan är registrerad använder du BackgroundTaskBuilder för att skapa en instans av bakgrundsaktiviteten. Startpunkten för uppgiften ska vara namnet på din bakgrundsuppgiftsklass med namnområdet som prefix.
Utlösaren för bakgrundsaktiviteten styr när bakgrundsaktiviteten ska köras. En lista över möjliga utlösare finns i SystemTrigger.
Den här koden skapar till exempel en ny bakgrundsaktivitet och anger att den ska köras när utlösaren TimeZoneChanged inträffar:
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
if (!taskRegistered)
{
Windows::ApplicationModel::Background::BackgroundTaskBuilder builder;
builder.Name(exampleTaskName);
builder.TaskEntryPoint(L"Tasks.ExampleBackgroundTask");
builder.SetTrigger(Windows::ApplicationModel::Background::SystemTrigger{
Windows::ApplicationModel::Background::SystemTriggerType::TimeZoneChange, false });
// The code in the next step goes here.
}
auto builder = ref new BackgroundTaskBuilder();
builder->Name = exampleTaskName;
builder->TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder->SetTrigger(ref new SystemTrigger(SystemTriggerType::TimeZoneChange, false));
- Du kan lägga till ett villkor för att styra när aktiviteten ska köras när utlösarhändelsen inträffar (valfritt). Om du till exempel inte vill att aktiviteten ska köras förrän användaren finns använder du villkoret UserPresent. En lista över möjliga villkor finns i SystemConditionType.
Följande exempelkod tilldelar ett villkor som kräver att användaren finns:
builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
builder.AddCondition(Windows::ApplicationModel::Background::SystemCondition{ Windows::ApplicationModel::Background::SystemConditionType::UserPresent });
// The code in the next step goes here.
builder->AddCondition(ref new SystemCondition(SystemConditionType::UserPresent));
- Registrera bakgrundsaktiviteten genom att anropa metoden Register på BackgroundTaskBuilder-objektet. Lagra BackgroundTaskRegistration resultat så att det kan användas i nästa steg.
Följande kod registrerar bakgrundsaktiviteten och lagrar resultatet:
BackgroundTaskRegistration task = builder.Register();
Windows::ApplicationModel::Background::BackgroundTaskRegistration task{ builder.Register() };
BackgroundTaskRegistration^ task = builder->Register();
Anmärkning
Universella Windows-appar måste anropa RequestAccessAsync innan du registrerar någon av typerna av bakgrundsutlösare.
För att säkerställa att din Universella Windows-app fortsätter att köras korrekt när du har släppt en uppdatering använder du utlösaren ServicingComplete (se SystemTriggerType) för att utföra eventuella konfigurationsändringar efter uppdateringen, till exempel migrera appens databas och registrera bakgrundsuppgifter. Det är bästa praxis att avregistrera bakgrundsaktiviteter som är associerade med den tidigare versionen av appen (se RemoveAccess) och registrera bakgrundsuppgifter för den nya versionen av appen (se RequestAccessAsync) för tillfället.
Mer information finns i Riktlinjer för bakgrundsaktiviteter.
Hantera slutförd bakgrundsaktivitet med hjälp av händelsehanterare
Du bör registrera en metod med BackgroundTaskCompletedEventHandler, så att appen kan få resultat från bakgrundsaktiviteten. När appen startas eller återupptas anropas den markerade metoden om bakgrundsaktiviteten har slutförts sedan den senaste gången appen var i förgrunden. (Metoden OnCompleted anropas omedelbart om bakgrundsaktiviteten slutförs medan din app för närvarande är i förgrunden.)
- Skriv en OnCompleted-metod för att hantera slutförandet av bakgrundsaktiviteter. Till exempel kan resultatet av bakgrundsaktiviteten orsaka en användargränssnittsuppdatering. Metodens fotavtryck som visas här krävs för händelsehanterarmetoden OnCompleted, även om det här exemplet inte använder parametern args.
Följande exempelkod identifierar slutförande av bakgrundsaktiviteter och anropar en exempelmetod för uppdatering av användargränssnittet som tar en meddelandesträng.
private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
{
var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
var key = task.TaskId.ToString();
var message = settings.Values[key].ToString();
UpdateUI(message);
}
void UpdateUI(winrt::hstring const& message)
{
MyTextBlock().Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]()
{
MyTextBlock().Text(message);
});
}
void OnCompleted(
Windows::ApplicationModel::Background::BackgroundTaskRegistration const& sender,
Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs const& /* args */)
{
// You'll previously have inserted this key into local settings.
auto settings{ Windows::Storage::ApplicationData::Current().LocalSettings().Values() };
auto key{ winrt::to_hstring(sender.TaskId()) };
auto message{ winrt::unbox_value<winrt::hstring>(settings.Lookup(key)) };
UpdateUI(message);
}
void MainPage::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
auto settings = ApplicationData::Current->LocalSettings->Values;
auto key = task->TaskId.ToString();
auto message = dynamic_cast<String^>(settings->Lookup(key));
UpdateUI(message);
}
Anmärkning
Användargränssnittsuppdateringar bör utföras asynkront för att undvika att hålla upp användargränssnittstråden. Ett exempel finns i metoden UpdateUI i bakgrundsaktivitetsexempel.
- Gå tillbaka till platsen där du registrerade bakgrundsaktiviteten. Efter den kodraden lägger du till ett nytt BackgroundTaskCompletedEventHandler- objekt. Ange din OnCompleted-metod som parameter för BackgroundTaskCompletedEventHandler konstruktor.
Följande exempelkod lägger till en BackgroundTaskCompletedEventHandler till BackgroundTaskRegistration:
task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
task.Completed({ this, &MainPage::OnCompleted });
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &MainPage::OnCompleted);
Deklarera i appmanifestet att appen använder bakgrundsuppgifter
Innan appen kan köra bakgrundsaktiviteter måste du deklarera varje bakgrundsaktivitet i appmanifestet. Om appen försöker registrera en bakgrundsaktivitet med en utlösare som inte visas i manifestet misslyckas registreringen av bakgrundsaktiviteten med felet "körningsklassen är inte registrerad".
- Öppna paketmanifestdesignern genom att öppna filen Package.appxmanifest.
- Öppna fliken -deklarationer.
- I listrutan Tillgängliga deklarationer väljer du alternativet Bakgrundsaktiviteter och klickar på Lägg till.
- Markera kryssrutan Systemhändelse.
- I textrutan Startpunkt: anger du namnområdet och namnet på din bakgrundsklass, som i det här exemplet är Tasks.ExampleBackgroundTask.
- Stäng manifestdesignern.
Följande tilläggselement läggs till i filen Package.appxmanifest för att registrera bakgrundsaktiviteten:
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.ExampleBackgroundTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
</Extensions>
Sammanfattning och nästa steg
Nu bör du förstå grunderna i hur du skriver en bakgrundsaktivitetsklass, hur du registrerar bakgrundsaktiviteten inifrån din app och hur du gör så att appen känner igen när bakgrundsaktiviteten är klar. Du bör också förstå hur du uppdaterar programmanifestet så att appen kan registrera bakgrundsaktiviteten.
Anmärkning
Ladda ned exempel på bakgrundsaktiviteter för att se liknande kodexempel i kontexten för en fullständig och robust UWP-app som använder bakgrundsaktiviteter.
Se följande relaterade ämnen för API-referens, konceptuell vägledning för bakgrundsaktiviteter och mer detaljerade instruktioner för att skriva appar som använder bakgrundsuppgifter.
Relaterade ämnen
Detaljerade instruktionsämnen för bakgrundsaktiviteter
- Svara på systemhändelser med bakgrundsaktiviteter
- Registrera en bakgrundsaktivitet
- Ange villkor för att köra en bakgrundsaktivitet
- Använd en underhållsutlösare
- Hantera en avbruten bakgrundsaktivitet
- Övervaka förlopp och slutförande av bakgrundsaktiviteter
- Kör en bakgrundsaktivitet på en timer-
- Skapa och registrera en pågående bakgrundsaktivitet.
- Konvertera en bakgrundsaktivitet utanför processen till en bakgrundsaktivitet inom processen
Vägledning för bakgrundsuppgifter
- Riktlinjer för bakgrundsaktiviteter
- Felsöka en bakgrundsaktivitet
- Så här utlöser du paus-, återuppta- och bakgrundshändelser i UWP-appar (vid felsökning)
API-referens för bakgrundsprocesser