Informationen
Das angeforderte Thema wird unten angezeigt. Es ist jedoch nicht in dieser Bibliothek vorhanden.

Schnellstart: Verwendung des Dispose-Modells in WinJS

Applies to Windows and Windows Phone

Erfahren Sie, wie Sie das Dispose-Modell in WinJS einsetzen können, um die Speicherauslastung der Steuerelemente und der anderen Objekte in einer Windows Store-App mit JavaScript zuverlässig zu steuern. Das Dispose-Modell ermöglicht das Erstellen von Steuerelementen, die ihren Speicher freigeben, wenn sie den gültigen Bereich verlassen haben. Das Objekt wird zum Löschen markiert, d. h. dass der Garbage Collector (ein Hintergrundprozess zur Verwaltung der Speicherauslastung) das Objekt zerstört.

Hinweis  Sie können die Windows-Leistungsaufzeichnung und die Windows-Leistungsanalyse verwenden, um zu verfolgen, wie Ihre App den Arbeitsspeicher nutzt. Weitere Informationen zur Windows-Leistungsaufzeichnung und Windows-Leistungsanalyse erhalten Sie unter Technische Referenz für Windows Performance Toolkit.

Voraussetzungen

Anweisungen

Erstellen eines neues Projekts mit der Vorlage "Leere App"

In diesem Artikel wird eine einfache Vorlage Leere App in Microsoft Visual Studio 2013 verwendet. Führen Sie die folgenden Schritte aus, um eine neue Leere App zu erstellen:

  1. Starten Sie Microsoft Visual Studio.

  2. Klicken Sie auf der Registerkarte Startseite auf Neues Projekt. Das Dialogfeld Neues Projekt wird geöffnet.

  3. Erweitern Sie im Bereich Installiert die Einträge Vorlagen, JavaScript und Store-Apps. Wählen Sie den Typ von App aus, den Sie erstellen möchten (Windows, Windows Phone, Allgemein). Die verfügbaren Projektvorlagen für JavaScript werden im mittleren Fenster des Dialogfelds angezeigt.

  4. Wählen Sie im mittleren Bereich die Projektvorlage Leere App aus.

  5. Geben Sie im Textfeld Name den Namen Dispose demo ein.
  6. Klicken Sie auf OK, um das Projekt zu erstellen.

Hinzufügen eines benutzerdefinierten Steuerelements zum Projekt

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner js, und klicken Sie auf Hinzufügen und dann auf Neue JavaScript-Datei. Geben Sie der neuen Datei im Dialogfeld Neues Element hinzufügen den Namen RandomShapesControl.js, und klicken Sie dann auf Hinzufügen.
  2. Öffnen Sie default.html, und fügen Sie das folgende <script>-Tag in das <head>-Tag ein.
    
    <script src="/js/RandomShapesControl.js"></script>
    
    
  3. Öffnen Sie die Datei RandomShapesControl.js (im Ordner js), und fügen Sie folgenden Code hinzu:
    
    
    (function () {
        "use strict";
    
        var svgNS = "http://www.w3.org/2000/svg";
    
        // Define a utility function for building HTML elements.
        function buildElement(type, attributes, text, namespace) {
            var newElement = namespace ?
                document.createElementNS(namespace, type) : document.createElement(type);
            for (var i in attributes) {
                if (attributes.hasOwnProperty(i)) {
                    newElement.setAttribute(i, attributes[i]);
                }
            }
            newElement.innerText = text || "";
            return newElement;
        }
    
        // Draw a randomly-colored rectangle onto the 'svg' container
        // element.
        function drawShape() {
            var newShape = buildElement("rect", {
                width: "30",
                height: "30",
                x: (Math.floor(Math.random() * 470) + 1).toString(),
                y: (Math.floor(Math.random() * 470) + 1).toString(),
                fill: getRandomColor()
            }, null, svgNS);
    
            document.getElementById('svg').appendChild(newShape);
        }
    
        // Generate a random RGB value as a string.
        function getRandomColor() {
            var color = function () { return Math.floor(Math.random() * 256) + 1; }
            var colorString = "rgb(" + color().toString() + "," + color().toString() 
                + "," + color().toString() + ")";
    
            return colorString;
        }
    
        WinJS.Namespace.define("Shapes", {
            RandomShape: WinJS.Class.define(
    
                // Define the constructor function / class definition for the
                // custom Random Shapes control. The Random Shapes control draws
                // a lot of randomly-colored SVG rectangles when a button is clicked. 
                function (element) {
    
                    // Implement a standard WinJS control 'interface' so that
                    // the winControl property returns this constructor function.
                    this._element = element;
                    this._element.winControl = this;
    
                    // Create an SVG container element for the rectangles.
                    this.svg = buildElement("svg", {
                        id: "svg",
                        width: "500",
                        height: "500"
                    }, null, svgNS);
    
                    // Create a button to raise the click event for the control.
                    this.drawMany = buildElement("button", {
                        id: "drawMany"
                    }, "Draw a bunch of shapes");
    
                    element.appendChild(this.svg);
                    element.appendChild(document.createElement("br"));
                    element.appendChild(this.drawMany);
    
                    // Add the click event handler to call drawManyShapes, which
                    // adds a lot of SVG elements to the SVG container.
                    this.drawMany.addEventListener("click", this.drawManyShapes);
    
                }, {
    
                    // Insert 1,000 randomly-colored shapes into the 'svg' container.
                    drawManyShapes: function () {
                        for (var i = 0; i < 1000; i++) {
                            drawShape();
                        }
                    }
                })
        });
    })();
    
    

Hinzufügen des HTML- und JavaScript-Codes für die Beispiel-App

Diese Demo-App erstellt ein benutzerdefiniertes Steuerelement, das viele (1.000) SVG-Elemente erzeugt, wenn der Benutzer auf eine Schaltfläche klickt. Jedes Element verfügt über eine eindeutige Farbe und ist innerhalb des größeren SVG-Elements angeordnet, was zu einer Erhöhung des Speicherbedarfs führt.

Öffnen Sie default.html, und fügen Sie den folgenden HTML-Code in das <body>-Element ein. Der Code sollte ein direktes untergeordnetes Element des <body>-Elements sein. Dieser HTML-Code erstellt zwei <div>-Elemente. Eines der Elemente enthält das benutzerdefinierte Steuerelement, und das andere enthält eine Schaltfläche, die das benutzerdefinierte Steuerelement löscht.


<div>
    <h1>Custom random-shape generator control</h1><br/><br/>
    <p>Use the button below to dispose the Random Shapes control.</p>
    <button id="dispose">Dispose control</button>
</div><br/><br/>
<div id="randomShapes" data-win-control="Shapes.RandomShape"></div>

Öffnen Sie die Datei default.js (im Ordner js), und ersetzen Sie den app.onactivated-Ereignishandler durch den folgenden Code. Mit diesem JavaScript-Code wird ein neues RandomShapes-Steuerelement erstellt und der Schaltfläche Dispose control ein Ereignishandler hinzugefügt.


app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
            // TODO: This appl has been newly launched. Initialize
            // your app here.
        } else {
            // TODO: This app has been reactivated from suspension.
            // Restore app state here.
        }

        args.setPromise(WinJS.UI.processAll().done(
            function () {

                // Add an event handler to the 'Dispose control' button.
                dispose.addEventListener("click", function () {
                    var shapesContainer = document.getElementById("randomShapes");
                    var shapesControl = shapesContainer.winControl;

                    shapesContainer.innerHTML = "";
                    shapesContainer = null;
                });
            }
       ));
    }
};

Wenn Sie die Speicherauslastung der App mit dem Leistungs- und Diagnosetool in Visual Studio 2013 untersuchen, sehen Sie, dass die App dem Steuerelement noch etwas Arbeitsspeicher zugeordnet hat, obwohl durch das Festlegen der innerHTML-Eigenschaft des Containerobjekts auf eine leere Zeichenfolge eigentlich der gesamte HTML-Code zerstört werden soll. Beiden Elementen ist immer noch Arbeitsspeicher zugewiesen.

Implementieren des Dispose-Musters

Stellen Sie beim Erstellen eines benutzerdefinierten Steuerelements sicher, dass es keine Arbeitsspeicherverluste in Ihrer App verursacht. In WinJS können benutzerdefinierte Steuerelemente das Dispose-Muster verwenden, um Arbeitsspeicher freizugeben, wenn das Steuerelement von der App nicht mehr benötigt wird.

Es gibt zwei grundlegende Anforderungen in Bezug auf die Implementierung des Dispose-Musters in einem benutzerdefinierten Steuerelement unter WinJS:

  • Der Container für das Steuerelement muss mit der CSS-Klasse (Cascading Stylesheets) "win-disposable" gekennzeichnet sein. Das HTML-Element, in dem das benutzerdefinierte Steuerelement enthalten ist, muss über ein class-Attribut mit dem Wert "win-disposable" verfügen.
  • Die Klassendefinition des Steuerelements muss einen dispose-Member enthalten. Wenn eine neue Klasse mit der WinJS.Class.define-Funktion deklariert wird, müssen die Instanzmember der Klasse eine dispose-Funktion enthalten.

Führen Sie zum Verbessern der Speicherauslastung des RandomShapes-Steuerelements in dieser Beispiel-App die folgenden Schritte aus, um den Code zu ändern, mit dem das Dispose-Muster implementiert wird.

  1. Öffnen Sie RandomShapesControl.js (im Ordner js). Fügen Sie in der Konstruktorfunktion für das RandomShapes-Steuerelement die folgende Codezeile hinzu:
    
    WinJS.Utilities.addClass(element, "win-disposable");
    
    
  2. Ersetzen Sie in RandomShapesControl.js außerdem den Aufruf von WinJS.Namespace.define durch den folgenden Code:
    
    WinJS.Namespace.define("Shapes", {
        RandomShape: WinJS.Class.define(Control, {
            drawManyShapes: drawManyShapes,
            dispose: function () {
    
                // Remove the click-event handler from the button.
                this.drawMany.removeEventListener("click", this.drawManyShapes);
    
                // Dispose of all the child controls of this element.
                WinJS.Utilities.disposeSubTree(this._element);
    
                // Release memory from all of the class fields.
                this.svg = null;
                this.drawMany = null;
                this._element = null;
            }
        })
    });
    
    
  3. Ersetzen Sie in default.js (im Ordner js) den Aufruf von args.setPromise durch den folgenden Code. Dieser Code ruft RandomShape.dispose explizit auf, um das Steuerelement zu löschen.
    
    args.setPromise(WinJS.UI.processAll().done(
        function () {
            dispose.addEventListener("click", function () {
                var shapesContainer = document.getElementById("randomShapes");
                var shapesControl = shapesContainer.winControl;
                
                // Call dispose on the control.
                shapesControl.dispose();
    
                shapesContainer.innerHTML = "";
                shapesContainer = null;
            })
        }
    ));
    
    

Hier sehen Sie den vollständigen, aktualisierten Code für RandomShapesControl.js.



   (function () {
    "use strict";

    var svgNS = "http://www.w3.org/2000/svg";

    // Define an internal utility function for building HTML elements.
    function buildElement(type, attributes, text, namespace) {
        var newElement = namespace ?
            document.createElementNS(namespace, type) : document.createElement(type);
        for (var i in attributes) {
            if (attributes.hasOwnProperty(i)) {
                newElement.setAttribute(i, attributes[i]);
            }
        }
        newElement.innerText = text || "";
        return newElement;
    }

    // Draw a randomly colored rectangle onto the 'svg' container
    // element.
    function drawShape() {
        var newShape = buildElement("rect", {
            width: "30",
            height: "30",
            x: (Math.floor(Math.random() * 470) + 1).toString(),
            y: (Math.floor(Math.random() * 470) + 1).toString(),
            fill: getRandomColor()
        }, null, svgNS);

        document.getElementById('svg').appendChild(newShape);
    }

    // Generate a random RGB value as a string.
    function getRandomColor() {
        var color = function () { return Math.floor(Math.random() * 256) + 1; }
        var colorString = "rgb(" + color().toString() + "," + color().toString() 
            + "," + color().toString() + ")";

        return colorString;
    }

    WinJS.Namespace.define("Shapes", {
        RandomShape: WinJS.Class.define(

            // Define the constructor function / class definition for the
            // custom Random Shapes control. The Random Shapes control draws
            // a lot of randomly colored SVG rectangles when a button is clicked. 
            function (element) {

                // Implement a standard WinJS control 'interface' so that
                // the winControl property returns this constructor function.
                this._element = element;
                this._element.winControl = this;

                WinJS.Utilities.addClass(element, "win-disposable");

                // Create an SVG container element for the rectangles.
                this.svg = buildElement("svg", {
                    id: "svg",
                    width: "500",
                    height: "500"
                }, null, svgNS);

                // Create a button to raise the click event for the control.
                this.drawMany = buildElement("button", {
                    id: "drawMany"
                }, "Draw a bunch of shapes");

                element.appendChild(this.svg);
                element.appendChild(document.createElement("br"));
                element.appendChild(this.drawMany);

                // Add the click-event handler to call drawManyShapes, which
                // adds a lot of SVG elements to the SVG container.
                this.drawMany.addEventListener("click", this.drawManyShapes);

            }, {

                // Insert 1,000 randomly colored shapes into the 'svg' container.
                drawManyShapes: function () {
                    for (var i = 0; i < 1000; i++) {
                        drawShape();
                    }
                },

                // Release all references to internal objects.
                dispose: function () {

                    // Remove the click-event handler from the button.
                    this.drawMany.removeEventListener("click", this.drawManyShapes);

                    // Dispose of all the child controls of this element.
                    WinJS.Utilities.disposeSubTree(this._element);

                    // Release memory from all of the class fields.
                    this.svg = null;
                    this.drawMany = null;
                    this._element = null;
                }
            })
    });
})();

Wenn Sie die Beispiel-App nach dem Implementieren des Dispose-Musters ausführen, ist das Verhalten der Benutzeroberfläche absolut identisch: Wenn Sie auf Draw a bunch of shapes klicken, werden dem SVG-Element 1.000 Rechtecke mit unterschiedlichen Farben hinzugefügt. Wenn Sie auf Dispose control klicken, wird das Steuerelement gelöscht.

Zusammenfassung

In dieser Schnellstartanleitung haben Sie erfahren, wie Sie das Dispose-Muster in einem benutzerdefinierten Steuerelement in einer Windows-Runtime-App mit JavaScript implementieren. Themen wie das Löschen von untergeordneten Steuerelementen, die selbst WinJS-Steuerelemente sind, oder die Verwendung von WinJS.Utilities.markDisposable wurden nicht behandelt.

 

 

Anzeigen:
© 2014 Microsoft