Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Megjegyzés:
Ez a cikk a Windows-futtatókörnyezet (WinRT) BackgroundTaskBuilder API-val készült háttérfeladatokat ismerteti a Windows. ApplicationModel.Background névtér csomagidentitású alkalmazásokhoz, beleértve az UWP-t és a csomagolt asztali alkalmazásokat. Ha új alkalmazást hoz létre, vagy meglévő alkalmazást migrál Windows App SDK, tekintse meg a Az Windows alkalmazások háttérfeladatainak használata és Háttéri feladatmigrálási stratégia.
Megtudhatja, hogyan hozhat létre és regisztrálhat háttérfeladatot az alkalmazásban a Windows-futtatókörnyezet (WinRT) BackgroundTaskBuilder osztályban.
Háttérfeladat regisztrálása
Az BackgroundTask mintában talál egy teljes példát egy háttérfeladat Univerzális Windows-platform (UWP)-alkalmazásokban való regisztrálására.
Az alábbi példa egy 15 perces ismétlődő időzítőn futó Win32 COM-feladat regisztrációját mutatja be.
Háttérfeladat regisztrálásához először létre kell hoznia a BackgroundTaskBuilder osztály új példányát . Az BackgroundTaskBuilder osztály háttérfeladatokat hoz létre és regisztrál az alkalmazásban. Az alábbi példakód bemutatja, hogyan hozható létre az osztály új példánya BackgroundTaskBuilder :
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);
A RegisterBackgroundTaskWithSystem metódus három paramétert használ:
-
trigger: Az eseményindító, amely elindítja a háttérfeladatot. -
entryPointClsid: A háttérfeladat belépési pontjának osztályazonosítója. -
taskName: A háttérfeladat neve.
A RegisterBackgroundTaskWithSystem metódus létrehozza az BackgroundTaskBuilder osztály új példányát, és beállítja a háttérfeladat eseményindító- és belépésipont-osztályazonosítóját. A metódus ezután regisztrálja a háttérfeladatot a rendszeren.
Megjegyzés:
Ez az osztály nem agilis, ami azt jelenti, hogy figyelembe kell vennie a szálmodellt és a csomagolás viselkedését. További információ: Threading and Marshaling (C++/CX) és Az Windows-futtatókörnyezet objektumok használata többszálú környezetben (.NET).
Modern készenléti állapot kezelése háttérfeladatban
A BackgroundTaskBuilder és a kapcsolódó API-k már lehetővé teszik a csomagolt asztali alkalmazások számára a háttérfeladatok futtatását. Az API mostantól kibővíti ezeket az API-kat, hogy lehetővé tegye ezeknek az alkalmazásoknak a kód modern készenléti állapotban való végrehajtását. A frissítés olyan tulajdonságokat is hozzáad, amelyeket egy alkalmazás lekérdezhet annak megállapításához, hogy a rendszer szabályozni fogja-e az alkalmazás háttérfeladatait a modern készenléti állapotban az akkumulátor üzemidejének megőrzése érdekében. Ez olyan forgatókönyveket tesz lehetővé, mint a VoIP-hívásokat fogadó alkalmazások vagy a modern készenléti állapotból érkező leküldéses értesítések.
Megjegyzés:
Ebben a szakaszban a "csomagolt asztali alkalmazások" olyan Win32-alkalmazásokra utalnak, amelyek csomagidentitással rendelkeznek (például Asztali híd vagy Ritkán aláírt csomagolt alkalmazások), és belépési pontként fő (vagy wmain) függvényt használnak.
Az alábbi példa bemutatja, hogy egy alkalmazásfejlesztő hogyan használhatja a BackgroundTaskBuilder API-t, hogy legfeljebb egy feladatot regisztráljon a megadott tevékenységnévvel. A minta azt is bemutatja, hogyan ellenőrizheti és engedélyezheti a feladatregisztrációt, hogy modern készenléti állapotban fusson az alkalmazás legkritikusabb feladataihoz.
// 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);
Ellenőrizze, hogy a háttérfeladatok túllépték-e a ráfordítási keretüket a modern készenléti állapotban
Az alábbi mintakód bemutatja, hogy az alkalmazásfejlesztők hogyan használhatják a BackgroundWorkCost.WasApplicationThrottledInStandby és a BackgroundWorkCost.ApplicationEnergyUseLevel parancsot, hogy monitorozzák és reagáljanak arra, hogy háttérfeladataik kimerítsék az alkalmazás költségvetését. Az alkalmazásfejlesztő úgy reagálhat, hogy csökkenti a modern készenléti állapotban végzett alacsonyabb prioritású munkát. Vegye figyelembe, hogy ez az előző minta kódjára támaszkodik.
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;
}
Háttérfeladat energiahasználati trendjeinek monitorozása
Az alábbiakban a C++WinRT/C# mintakód incrementális végponttól végpontig történő frissítése található a GitHub-on.
A példa bemutatja, hogyan használhatja a BackgroundWorkCost.ApplicationEnergyUseTrendet annak figyelésére, hogy a háttérfeladatok hogyan trendelnek a költségvetésük kimerülése felé. Azt is megakadályozhatja, hogy a legdrágább háttérfeladatok modern készenléti állapotban fussanak, és megakadályozza, hogy a háttérfeladatok modern készenléti állapotban fussanak, ha az alkalmazás túl gyorsan használja a költségvetését. Ez a minta a korábbi minták kódjára támaszkodik.
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;
}
Háttérfeladatok és hálózati kapcsolat
Ha a háttérfeladat hálózati kapcsolatot igényel, vegye figyelembe az alábbi szempontokat.
Hálózattal kapcsolatos eseményindítók
- A SocketActivityTrigger használatával aktiválhatja a háttérfeladatot egy csomag érkezésekor, és rövid élettartamú feladatot kell végrehajtania. A feladat végrehajtása után a háttérfeladatnak le kell fejeződnie, hogy energiát takarítson meg.
- A ControlChannelTriggerrel aktiválhatja a háttérfeladatot egy csomag érkezésekor, és hosszú élettartamú feladatot kell végrehajtania.
Hálózattal kapcsolatos feltételek és jelzők
- Adja hozzá az InternetAvailable feltételt (BackgroundTaskBuilder.AddCondition) a háttérfeladathoz, hogy késleltetve aktiválja a háttérfeladatot, amíg a hálózati verem nem fut. Ez a feltétel energiát takarít meg, mert a háttérfeladat nem lesz végrehajtva, amíg el nem érhető a hálózati hozzáférés. Ez a feltétel nem biztosít valós idejű aktiválást.
- A használt eseményindítótól függetlenül állítsa be az IsNetworkRequested parancsot a háttérfeladatra, hogy a hálózat a háttérfeladat futtatása közben is megmaradjon. Ez azt jelzi a háttérfeladat-infrastruktúrának, hogy a feladat végrehajtása közben is tartsa fenn a hálózatot, még akkor is, ha az eszköz csatlakoztatott készenléti üzemmódba lépett. Ha a háttérfeladat nem használja az IsNetworkRequested szolgáltatást, akkor a háttérfeladat nem fogja tudni elérni a hálózatot csatlakoztatott készenléti módban.
Kapcsolódó tartalom
Windows developer