Verschieben der angehaltenen App mithilfe der erweiterten Ausführung

In diesem Artikel erfahren Sie, wie Sie die erweiterte Ausführung verwenden, um zu verschieben, wenn Ihre App angehalten wird, sodass sie minimiert oder unter dem Sperrbildschirm ausgeführt werden kann.

Wenn der Benutzer eine App minimiert oder sie verlässt, wird sie in einen angehaltenen Zustand versetzt. Der Arbeitsspeicher wird nicht gelöscht, der App-Code wird jedoch nicht ausgeführt. Dies gilt für alle Betriebssystemeditionen mit einer grafischen Benutzeroberfläche. Weitere Informationen zum Anhalten von Apps finden Sie unter Anwendungslebenszyklus.

Es gibt Fälle, in denen eine App möglicherweise weiterhin ausgeführt werden muss, anstatt angehalten zu werden, wenn der Benutzer von der App navigiert oder während sie minimiert ist. Beispielsweise muss eine Schrittzählungs-App die Schritte weiter ausführen und nachverfolgen, auch wenn der Benutzer weg navigiert, um andere Apps zu verwenden.

Wenn eine App weiter ausgeführt muss, kann sie entweder vom Betriebssystem weiter ausgeführt werden, oder sie kann die weitere Ausführung anfordern. Wenn beispielsweise im Hintergrund Audioinhalte wiedergegeben werden, kann das Betriebssystem eine App weiter ausführen, wenn Sie diese Schritte für Medienwiedergabe im Hintergrund ausführen. Andernfalls müssen Sie manuell mehr Zeit anfordern. Die Zeit, die Sie möglicherweise für die Ausführung im Hintergrund haben, kann mehrere Minuten betragen, aber Sie müssen jederzeit darauf vorbereitet sein, die sitzung zu verarbeiten, die widerrufen wird. Diese Zeiteinschränkungen für den Anwendungslebenszyklus sind deaktiviert, während die App unter einem Debugger ausgeführt wird. Aus diesem Grund ist es wichtig, die erweiterte Ausführung und andere Tools zu testen, um das Anhalten von Apps zu verschieben, während sie nicht unter einem Debugger ausgeführt werden, oder indem Sie die in Visual Studio verfügbaren Lebenszyklusereignisse verwenden.

Um mehr Zeit für das Ausführen eines Vorgangs im Hintergrund anzufordern, erstellen Sie eine ExtendedExecutionSession. Die Art von ExtendedExecutionSession , die Sie erstellen, wird durch die ExtendedExecutionReason bestimmt, die Sie beim Erstellen angeben. Es gibt drei Enumerationswerte für ExtendedExecutionReason: Unspecified, LocationTracking und SavingData. Es kann jederzeit nur eine ExtendedExecutionSession angefordert werden. Der Versuch, eine weitere Sitzung zu erstellen, während eine genehmigte Sitzungsanforderung aktuell aktiv ist, führt dazu, dass ausnahmebasierte 0x8007139F vom ExtendedExecutionSession-Konstruktor ausgelöst werden, der besagt, dass die Gruppe oder Ressource nicht im richtigen Zustand ist, um den angeforderten Vorgang auszuführen. Verwenden Sie nicht ExtendedExecutionForegroundSession und ExtendedExecutionForegroundReason. Sie erfordern eingeschränkte Funktionen und sind nicht für die Verwendung in Store-Anwendungen verfügbar.

Ausführen bei Minimierung

Es gibt zwei Fälle, in denen die erweiterte Ausführung verwendet werden kann:

  • Zu jedem Zeitpunkt während der regulären Vordergrundausführung, während sich die Anwendung im Ausführungszustand befindet.
  • Nachdem die Anwendung ein Angehaltenes Ereignis empfangen hat (das Betriebssystem ist dabei, die App in den Angehaltenen Zustand zu verschieben) im Angehaltenen Ereignishandler der Anwendung.

Der Code für diese beiden Fälle ist identisch, aber die Anwendung verhält sich in jedem etwas anders. Im ersten Fall verbleibt die Anwendung im Status "Wird ausgeführt", auch wenn ein Ereignis auftritt, das normalerweise das Anhalten auslösen würde (z. B. der Benutzer, der von der Anwendung weg navigiert). Die Anwendung empfängt nie ein Angehaltenes Ereignis, während die Ausführungserweiterung aktiv ist. Wenn die Erweiterung verworfen wird, kann die Anwendung wieder ausgesetzt werden.

Im zweiten Fall, wenn die Anwendung in den Angehaltenen Zustand wechselt, verbleibt sie für den Zeitraum der Erweiterung in einem angehaltenen Zustand. Sobald die Erweiterung abläuft, wechselt die Anwendung ohne weitere Benachrichtigung in den Angehaltenen Zustand.

Verwenden Sie ExtendedExecutionReason.Unspecified , wenn Sie eine ExtendedExecutionSession erstellen, um für Szenarien wie Medienverarbeitung, Projektkompilierung oder Aufrechterhalten einer Netzwerkverbindung zusätzliche Zeit anzufordern, bevor Ihre App in den Hintergrund wechselt. Auf Desktopgeräten, auf denen Windows 10-Editionen für Desktops ausgeführt werden (Home, Pro, Enterprise und Education), verwenden Sie diesen Ansatz, um zu vermeiden, dass eine App bei Minimierung angehalten wird.

Sie fordern die Erweiterung an, wenn ein über lange Zeit ausgeführter Vorgang gestartet wird, um den Wechsel in den Zustand Suspending zu verschieben, der andernfalls beim Verschieben der App in den Hintergrund ausgeführt wird. Auf Desktopgeräten gibt es für mit ExtendedExecutionReason.Unspecified erstellte erweiterte Ausführungssitzungen eine akkubasierte zeitliche Begrenzung. Wenn das Gerät an eine Steckdose angeschlossen ist, gibt es keine zeitliche Begrenzung für die erweiterte Ausführung. Wenn das Gerät mit Akku betrieben wird, kann der Zeitraum für die erweiterte Ausführung im Hintergrund bis zu zehn Minuten betragen.

Ein Tablet- oder Laptop-Benutzer kann das gleiche lange Laufverhalten erhalten – zu Lasten der Akkulaufzeit –, wenn die Option Ausführen von Hintergrundaufgaben durch die App zulassen unter Akkunutzung nach App-Einstellungen ausgewählt ist. (Um diese Option auf einem Laptop zu finden, wechseln Sie zu Einstellungen>.System>Batterie>Akkunutzung nach App (der Link unter dem Prozentsatz der verbleibenden Akkuleistung) > wählen Sie eine App > deaktivieren Verwaltet von Windows> aus, und wählen Sie App das Ausführen von Hintergrundaufgaben erlauben aus.

Diese Art der erweiterten Ausführung wird auf allen Betriebssystemeditionen beendet, wenn das Gerät in den Zustand „Verbundener Standbymodus“ versetzt wird. Auf mobilen Geräten mit Windows 10 Mobile wird diese Art von erweiterter Ausführung solange ausgeführt, wie der Bildschirm aktiviert ist. Wenn der Bildschirm deaktiviert wird, versucht das Gerät sofort, in den energiesparenden Zustand „Verbundener Standbymodus“ zu wechseln. Auf Desktopgeräten wird die Sitzung weiter ausgeführt, wenn der Sperrbildschirm angezeigt wird. Das Gerät wechselt nach Deaktivierung des Bildschirms für einen gewissen Zeitraum nicht in den Zustand „Verbundener Standbymodus“. In der Xbox-Betriebssystemedition wechselt das Gerät nach einer Stunde in den Zustand „Verbundener Standbymodus“, wenn der Benutzer die Standardeinstellung nicht geändert hat.

Abrufen des Standorts eines Benutzers

Geben Sie beim Erstellen einer ExtendedExecutionSessionExtendedExecutionReason.LocationTracking an, wenn Ihre App regelmäßig den Standort aus GeoLocator protokollieren muss. Apps für Fitnessnachverfolgung und Navigation, die regelmäßig den Standort des Benutzers überwachen müssen, sollten diesen Grund verwenden.

Eine Erweiterte Ausführungssitzung zur Standortnachverfolgung kann so lange wie erforderlich ausgeführt werden, auch wenn der Bildschirm auf einem mobilen Gerät gesperrt ist. Pro Gerät kann jedoch nur eine solche Sitzung ausgeführt werden. Eine erweiterte Ausführung zur Standortnachverfolgung kann nur im Vordergrund angefordert werden, und die App muss sich im Zustand Ausgeführt befinden. Dadurch wird sichergestellt, dass der Benutzer weiß, dass die App die erweiterte Ausführung zur Standortnachverfolgung initiiert hat. GeoLocator kann mittels einer Hintergrundaufgabe oder eines App-Diensts während der Ausführung der App im Hintergrund weiter verwendet werden, ohne dass eine erweiterte Ausführung zur Standortnachverfolgung angefordert wird.

Lokales Speichern wichtiger Daten

Geben Sie beim Erstellen einer ExtendedExecutionSessionExtendedExecutionReason.SavingData an, wenn Sie in Fällen, in das Nichtspeichern von Daten vor Beenden der App zu Datenverlusten und einer negativen Benutzererfahrung führt, Benutzerdaten speichern möchten.

Verwenden Sie diese Art von Sitzung nicht, um den Lebenszyklus einer App zum Zweck des Hoch- oder Herunterladens von Daten zu verlängern. Fordern Sie eine Hintergrundübertragung an, wenn Sie Daten hochladen müssen, oder registrieren Sie einen MaintenanceTrigger, um die Übertragung zu verarbeiten, wenn die Stromversorgung verfügbar ist. Eine erweiterte Ausführungssitzung mit dem Grund ExtendedExecutionReason.SavingData kann angefordert werden, wenn sich die App im Vordergrund und im Zustand Ausgeführt befindet oder wenn sie sich im Hintergrund und im Zustand Angehalten befindet.

Der Zustand Angehalten ist die letzte Phase während des App-Lebenszyklus, in der die App Aufgaben ausführen kann, bevor sie beendet wird. ExtendedExecutionReason.SavingData ist der einzige Typ von ExtendedExecutionSession , der im Status Anhaltend angefordert werden kann. Das Anfordern einer erweiterten Ausführungssitzung mit dem Grund ExtendedExecutionReason.SavingData, während sich die App im Zustand Angehalten befindet, kann ein Problem verursachen, das Sie beachten sollten. Wenn im Zustand Suspending eine erweiterte Ausführungssitzung angefordert wird, und der Benutzer das erneute Starten der App anfordert, benötigt sie zum Starten scheinbar eine lange Zeit. Der Grund hierfür ist, dass die erweiterte Ausführungssitzung abgeschlossen werden muss, bevor die alte Instanz der App geschlossen und eine neue Instanz der App gestartet werden kann. Es wird auf Leistung beim Starten verzichtet, um sicherzustellen, dass der Benutzerstatus nicht verloren geht.

Anfordern, Löschen und Sperren

Es gibt drei grundsätzliche Interaktionen mit erweiterten Ausführungssitzungen: Anfordern, Löschen und Sperren. Das Anfordern wird im folgenden Codeausschnitt gezeigt.

Anforderung

var newSession = new ExtendedExecutionSession();
newSession.Reason = ExtendedExecutionReason.Unspecified;
newSession.Revoked += SessionRevoked;
ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

switch (result)
{
    case ExtendedExecutionResult.Allowed:
        DoLongRunningWork();
        break;

    default:
    case ExtendedExecutionResult.Denied:
        DoShortRunningWork();
        break;
}

Siehe Codebeispiel

Durch Aufrufen von RequestExtensionAsync wird durch das Betriebssystem geprüft, ob der Benutzer Hintergrundaktivitäten für die App genehmigt hat und ob das System über genügend Ressourcen verfügt, um die Hintergrundausführung zu aktivieren. Es wird jederzeit nur eine Sitzung für eine App genehmigt, was dazu führt, dass zusätzliche Aufrufe von RequestExtensionAsync dazu führen, dass die Sitzung verweigert wird.

Sie können BackgroundExecutionManager im Voraus überprüfen, um den BackgroundAccessStatus zu ermitteln. Dies ist die Benutzereinstellung, die festlegt, ob Ihre App im Hintergrund ausgeführt werden kann oder nicht. Weitere Informationen zu diesen Benutzereinstellungen finden Sie unter Hintergrundaktivitäten und Energieinformationen.

Der ExtendedExecutionReason gibt den Vorgang an, der von Ihrer App im Hintergrund ausgeführt wird. Die Zeichenfolge Beschreibung ist eine lesbare Zeichenfolge, die beschreibt, warum Ihre App den Vorgang ausführen muss. Diese Zeichenfolge wird dem Benutzer nicht angezeigt, kann aber in einer zukünftigen Version von Windows verfügbar gemacht werden. Der Ereignishandler Revoked ist erforderlich, damit eine erweiterte Ausführungssitzung ordnungsgemäß angehalten werden kann, wenn der Benutzer oder das System festlegen, dass die App nicht mehr im Hintergrund ausgeführt werden kann.

Widerrufen

Wenn eine App über eine aktive erweiterte Ausführungssitzung verfügt und das System eine Hintergrundaktivität zum Anhalten benötigt, da eine Vordergrundanwendung die Ressourcen benötigt, wird die Sitzung widerrufen. Der Zeitraum für eine erweiterte Ausführungssitzung wird nie beendet, ohne dass zuerst der Ereignishandler Revoked aufgerufen wird.

Wenn das Ereignis Revoked für eine erweiterte Ausführungssitzung mit dem Grund ExtendedExecutionReason.SavingData ausgelöst wird, hat die App nur eine Sekunde Zeit, um den gerade ausgeführten Vorgang abzuschließen und den Zustand Angehalten zu beenden.

Das Sperren kann aus verschiedenen Gründen erfolgen: das Erreichen der zeitlichen Begrenzung für die Ausführung, das Erreichen der Begrenzung für den Energieverbrauch für Hintergrundaufgaben oder das notwendige Freigeben von Arbeitsspeicher, damit der Benutzer eine neue App im Vordergrund öffnen kann.

Im Folgenden wird Ihnen ein Beispiel für den Ereignishandler „Revoked“ angezeigt:

private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        switch (args.Reason)
        {
            case ExtendedExecutionRevokedReason.Resumed:
                rootPage.NotifyUser("Extended execution revoked due to returning to foreground.", NotifyType.StatusMessage);
                break;

            case ExtendedExecutionRevokedReason.SystemPolicy:
                rootPage.NotifyUser("Extended execution revoked due to system policy.", NotifyType.StatusMessage);
                break;
        }

        EndExtendedExecution();
    });
}

Siehe Codebeispiel

Dispose

Der letzte Schritt besteht im Löschen der erweiterten Ausführungssitzung. Sie sollten die Sitzung und alle weiteren, Arbeitsspeicher in Anspruch nehmenden Ressourcen löschen, da andernfalls die von der App beim Warten auf das Beenden der Sitzung verbrauchte Energie auf das Energiekontingent der App angerechnet wird. Um einen möglichst großen Teil des Energiekontingents der App zu bewahren, ist es wichtig, die Sitzung zu löschen, wenn sie nicht mehr benötigt wird, damit die App schneller in den Zustand Angehalten wechseln kann.

Wenn Sie die Sitzung selbst löschen, statt auf das Sperrereignis zu warten, wird die Energiekontingentnutzung Ihrer App reduziert. Das bedeutet, dass Ihre App zukünftig länger im Hintergrund ausgeführt werden darf, da ihr hierfür ein größeres Energiekontingent zur Verfügung steht. Sie müssen bis zum Abschluss des Vorgangs einen Verweis auf das Objekt ExtendedExecutionSession beibehalten, damit Sie dessen Methode Dispose aufrufen können.

Im Folgenden wird ein Codeausschnitt angezeigt, in dem eine erweiterte Ausführungssitzung gelöscht wird:

void ClearExtendedExecution(ExtendedExecutionSession session)
{
    if (session != null)
    {
        session.Revoked -= SessionRevoked;
        session.Dispose();
        session = null;
    }
}

Siehe Codebeispiel

Für eine App kann jeweils nur eine ExtendedExecutionSession aktiv sein. Viele Apps verwenden asynchrone Aufgaben, um komplexe Vorgänge ausführen, die Zugriff auf Ressourcen wie Speicher, Netzwerk oder netzwerkbasierte Dienste erfordern. Wenn ein Vorgang mehrere asynchrone Vorgänge erfordert, um abgeschlossen zu werden, muss der Zustand jeder dieser Aufgaben berücksichtigt werden, bevor ExtendedExecutionSession gelöscht wird und die App angehalten werden kann. Dies erfordert eine Verweiszählung der Anzahl der Aufgaben, die weiter ausgeführt werden. Erst wenn dieser Wert null erreicht, kann die Sitzung gelöscht werden.

Im Folgenden finden Sie einen Beispielcode zum Verwalten mehrerer Aufgaben während eines erweiterten Ausführungssitzungszeitraums. Weitere Informationen zur Verwendung in Ihrer App finden Sie im unten verlinkten Codebeispiel:

static class ExtendedExecutionHelper
{
    private static ExtendedExecutionSession session = null;
    private static int taskCount = 0;

    public static bool IsRunning
    {
        get
        {
            if (session != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public static async Task<ExtendedExecutionResult> RequestSessionAsync(ExtendedExecutionReason reason, TypedEventHandler<object, ExtendedExecutionRevokedEventArgs> revoked, String description)
    {
        // The previous Extended Execution must be closed before a new one can be requested.       
        ClearSession();

        var newSession = new ExtendedExecutionSession();
        newSession.Reason = reason;
        newSession.Description = description;
        newSession.Revoked += SessionRevoked;

        // Add a revoked handler provided by the app in order to clean up an operation that had to be halted prematurely
        if(revoked != null)
        {
            newSession.Revoked += revoked;
        }

        ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

        switch (result)
        {
            case ExtendedExecutionResult.Allowed:
                session = newSession;
                break;
            default:
            case ExtendedExecutionResult.Denied:
                newSession.Dispose();
                break;
        }
        return result;
    }

    public static void ClearSession()
    {
        if (session != null)
        {
            session.Dispose();
            session = null;
        }

        taskCount = 0;
    }

    public static Deferral GetExecutionDeferral()
    {
        if (session == null)
        {
            throw new InvalidOperationException("No extended execution session is active");
        }

        taskCount++;
        return new Deferral(OnTaskCompleted);
    }

    private static void OnTaskCompleted()
    {
        if (taskCount > 0)
        {
            taskCount--;
        }
        
        //If there are no more running tasks than end the extended lifetime by clearing the session
        if (taskCount == 0 && session != null)
        {
            ClearSession();
        }
    }

    private static void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
    {
        //The session has been prematurely revoked due to system constraints, ensure the session is disposed
        if (session != null)
        {
            session.Dispose();
            session = null;
        }
        
        taskCount = 0;
    }
}

Siehe Codebeispiel

Gute Nutzung von Ressourcen durch Ihre App

Das Optimieren von Arbeitsspeicher und Energieverbrauch Ihrer App ist der Schlüssel, um sicherzustellen, dass das Betriebssystem die Ausführung Ihrer App auch dann zulässt, wenn sie sich nicht mehr im Vordergrund befindet. Um zu ermitteln, wie viel Arbeitsspeicher Ihre App verwendet, verwenden Sie die Speicherverwaltungs-APIs. Je mehr Arbeitsspeicher Ihre App verwendet, desto schwieriger wird es für das Betriebssystem, Ihre App weiter auszuführen, wenn sich eine andere App im Vordergrund befindet. Der Benutzer hat letztendlich die Kontrolle über alle Hintergrundaktivitäten, die Ihre App ausführen kann, und kann die Auswirkungen Ihrer App auf den Akkuverbrauch erkennen.

Um zu ermitteln, ob der Benutzer die Hintergrundaktivität Ihrer App begrenzt hat, verwenden Sie BackgroundExecutionManager.RequestAccessAsync. Achten Sie auf die Akkunutzung, und führen Sie Ihre App nur dann im Hintergrund aus, wenn dies zum Ausführen einer vom Benutzer gewünschten Aktion notwendig ist.

Siehe auch

Beispiel für die erweiterte Ausführung
Anwendungslebenszyklus
App-Lebenszyklus: Halten Sie Apps mit Hintergrundaufgaben und erweiterterSpeicherverwaltung für die Ausführung im Hintergrund am Leben
Hintergrundübertragungen
Akku-Bewusstsein und Hintergrundaktivität
MemoryManager-Klasse
Wiedergeben von Medien im Hintergrund