So wird's gemacht: Behandeln von Hintergrundaufgaben, die sich im Leerlauf befinden oder nicht mehr reagieren

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Hintergrundaufgaben im Leerlauf können eine unnötige Beendigung der App verursachen. Behandeln Sie Hintergrundaufgaben, die im Leerlauf sind (oder nicht mehr reagieren), indem Sie den Abbruch behandeln und die Hintergrundaufgabe komplett beenden.

Hintergrundaufgaben sind Aufgaben von kurzer Dauer, die ihre Arbeit schnell ausführen und deren Rückgabe ebenso schnell erfolgt. Dieses Verhalten ist aufgrund der strikten CPU- und Netzwerkressourceneinschränkungen für Hintergrundaufgaben erforderlich. Hintergrundaufgaben sind die einzige unterstützte Möglichkeit, um in der angehaltenen App und im verbundenen Standbymodus Code im Hintergrund auszuführen. Einschränkungen der Ressourcenverwendung beschränken die möglichen Auswirkungen von Hintergrundaufgaben auf die Akkulaufzeit.

Damit diese Einschränkungen angewendet werden, ermittelt die Hintergrundaufgabeninfrastruktur Hintergrundaufgaben, die sich im Leerlauf befinden oder nicht mehr reagieren. Wenn eine Hintergrundaufgabe nicht innerhalb einer bestimmten Mindestzeit ein Mindestkontingent an CPU- oder Netzwerkressourcen genutzt hat, gilt sie als im Leerlauf befindlich oder aufgehängt. Die Mindestzeit hängt vom Systemzustand ab, z. B. davon, ob das System im verbundenen Standbymodus ist. Wird eine Hintergrundaufgabe erkannt, die im Leerlauf ist oder nicht mehr reagiert, wird eine Abbruchbenachrichtigung an die Aufgabe gesendet, damit sie sauber beendet werden kann. Reagiert die Hintergrundaufgabe nicht innerhalb von fünf Sekunden durch vollständige Beendigung auf die Abbruchbenachrichtigung, geht das System davon aus, dass die App nicht mehr reagiert und beendet sie. (In diesem Fall wird ein WER-Absturzabbildbericht generiert, der in Ihrem Windows Store-Entwicklerkonto verfügbar ist.)

Wenn Hintergrundaufgaben im Leerlauf sind oder nicht mehr reagieren, liegt dies meist daran, dass sie auf den Abschluss eines asynchronen Vorgangs in der Run()-Methode warten. Dies kann z. B. passieren, wenn sie auf eine Antwort von einem Netzwerksocket warten, oder bei einem langem Dateikopiervorgang, bei dem der Datenträger nicht reagiert. Gehen Sie wie im Folgenden beschrieben vor, um den Abbruch von Hintergrundaufgaben sauber zu behandeln (auch wenn sie auf asynchrone Vorgänge warten).

Wissenswertes

Technologien

Voraussetzungen

  • Dieses Thema gilt für Apps mit Hintergrundaufgaben.

Anweisungen

Schritt 1: Registrieren eines Abbruchhandlers

Registrieren Sie immer einen Abbruchhandler für Ihre Hintergrundaufgabe. Das System erkennt, dass die Hintergrundaufgabe sich im Leerlauf befindet oder nicht mehr reagiert, wenn der Abbruchhandler aufgerufen wird. Ihre Hintergrundaufgabe muss über einen Abbruchhandler verfügen, und dieser muss dafür sorgen, dass die Aufgabe innerhalb von fünf Sekunden komplett beendet wird. Andernfalls wird Ihre App beendet.

Schritt 2: Abbrechen asynchroner Vorgänge

Einige Aufgaben scheinen sich im Leerlauf zu befinden, wenn sie auf asynchrone Vorgänge warten, die in der Run()-Methode erstellt wurden. Eine einfache Möglichkeit zum Abbrechen aller ausstehenden asynchronen Vorgänge besteht darin, allen asynchronen Vorgängen eine einzige "CancellationTokenSource" zuzuordnen. Anschließend rufen Sie im Abbruchhandler einfach "Cancel" für die "CancellationTokenSource" auf, um alle ausstehenden asynchronen Vorgänge abzubrechen.

Schritt 3: Beenden der Hintergrundaufgabenverzögerung

In JavaScript muss die Hintergrundaufgabe nach Abschluss ihrer Arbeit "close()" aufrufen, damit sie beendet werden kann. Ohne eine close()-Anweisung am Ende geht die Hintergrundaufgabeninfrastruktur davon aus, dass die Aufgabe noch ausgeführt wird und lässt den JavaScript-Host aktiv. Wird eine JavaScript-Hintergrundaufgabe ohne close()-Aufruf beendet, geht das System davon aus, dass sie sich im Leerlauf befindet oder nicht mehr reagiert, und sendet eine Abbruchbenachrichtigung.

Anmerkungen

Bewährte Methoden für Hintergrundaufgaben, die sich im Leerlauf befinden oder nicht mehr reagieren

Verwenden Sie für Hintergrundaufgaben, die sich im Leerlauf befinden oder nicht mehr reagieren, die folgenden bewährten Methoden.

  1. Ordnen Sie Ihren Hintergrundaufgaben immer einen Abbruchhandler zu.
  2. Brechen Sie in Ihrem Abbruchhandler alle asynchronen Vorgänge ab, und beenden Sie die Hintergrundaufgabe innerhalb von fünf Sekunden. Andernfalls wird Ihre App beendet.
  3. Rufen Sie unmittelbar vor dem Beenden Ihrer Java-Hintergrundaufgabe "close()" auf.

Beispielcode

Die folgende Hintergrundaufgabe registriert einen Abbruchhandler, bricht asynchrone Vorgänge ab und ruft "close()" auf.

(function () {
    "use strict";

    var cancelOperation = null;

    var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;

    // Associate a cancellation handler with the background task.
    function onCanceled(cancelSender, cancelReason) {
        // The background task has been detected as idle or hung.
        // Cancel all pending async operations and return from the task.
        cancelOperation.cancel();
    }

    backgroundTaskInstance.addEventListener("canceled", onCanceled);

    // Main download function 
    function startDownload() {

        // Assign the URI to download from.
        var uriExample = new Windows.Foundation.Uri("https://www.contoso.com");

        // Get the folder for temporary files.
        var tempFolder = Windows.Storage.ApplicationData.current.temporaryFolder;

        // Create the temp file asynchronously.
        cancelOperation = tempFolder.createFileAsync("tempfile.txt")
           .then(function (tempFile) {
               // The createFileAsync call succeeded, so start the download operation.
               var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
               var transfer = downloader.createDownload(uriExample, tempFile);
               return transfer.startAsync();
           })
           .then(
               //Define the function to use when the download completes successfully.
               function (result) {
                   console.log("File download complete.");
               },
               // Define the error handling function.
               function (error) {
                   console.log("File download failed.");
               },
               // Define the progress handling function.
               function (progress) {
                   console.log("Bytes retrieved: " + progress.progress.bytesReceived);
               })
            .then (function () {
                // Always call close() before the task returns.
                close();
            }, function () {
                close();
            });    }

    startDownload(); 

})();

Verwandte Themen

So wird's gemacht: Behandeln einer abgebrochenen Hintergrundaufgabe