Überlegungen zur Leistung für Anwendungen, die Dienste verwenden

Aktualisiert: November 2007

In diesem Thema werden Verfahren zum Optimieren der Leistung beschrieben, wenn die ASP.NET-Features Mitgliedschaft, Rollen, Profileigenschaften, Sitzungszustand, Webparts-Personalisierung und Sitenavigation verwendet werden.

Mitgliedschaft

Dieser Abschnitt enthält Informationen über die effiziente Verwendung von ASP.NET-Mitgliedschaft.

Effizientes Erfassen von Mitgliedschaftslisten

Wenn Sie Methoden der Membership-Klasse aufrufen, rufen Sie die überladenen Methoden auf, die PageIndex-Member und PageSize-Member akzeptieren. Diese Überladungen werden schneller ausgeführt, da sie dazu führen, dass weniger Daten vom Webserver übertragen werden. Ein Beispiel hierfür ist die GetAllUsers-Methode der Membership-Klasse. Durch den Aufruf der GetAllUsers-Methode ohne Parameter werden alle Mitgliedschaftsbenutzer zurückgegeben. Hingegen wird durch den Aufruf der GetAllUsers-Überladung nur eine Seite mit Benutzern zurückgegeben, sodass sich die Menge der von der Seite verarbeiteten Daten verringert.

Zwischenspeichern von Ergebnissen beim Abrufen der Anzahl von Onlinebenutzern

Sie können die GetNumberOfUsersOnline-Methode aufrufen, um die Anzahl der Benutzer anzuzeigen, die als auf der Website aktiv erachtet werden. Diese Methode überprüft bei jedem Aufruf die einzelnen Zeilen in der Mitgliedschaftstabelle. Dies kann zu einer beträchtlichen Leistungseinbuße führen, wenn die Datenbank eine große Anzahl von Benutzern enthält. Rufen Sie die Methode nur auf, wenn dies erforderlich ist, und zwischenspeichern Sie den Wert für eine gewisse Zeitspanne, wenn Sie keine genaue Anzahl benötigen.

Rollen

Die GetRolesForUser-Methode wird standardmäßig bei jedem Laden einer Seite automatisch aufgerufen, und sie gibt die Rollen zurück, die ein Benutzer innehat. Die Rollen werden in einem Wörterbuch im RolePrincipal-Objekt gespeichert. Während der Ausführung der Seite erfolgt die Überprüfung auf Rollen mithilfe dieses Wörterbuchs. Um den Zugriff auf den Anbieter bei jedem Laden der Seite zu verhindern und so die Serververarbeitungszeit zu verringern, legen Sie das CacheRolesInCookie-Attribut in der Datei Web.config der Anwendung auf true fest. Hierdurch wird die Liste mit den Rollen des Benutzers in einem Cookie gespeichert. Wenn die Seite anschließend geladen wird, können die Rolleninformationen aus dem Cookie gelesen werden, statt den Anbieter aufzurufen.

In Code kann die Mitgliedschaft in einer Rolle mit der GetRolesForUser-Methode, der IsInRole-Eigenschaft und der GetRoles-Methode überprüft werden. Wenn Sie wissen, wie diese Methoden interagieren, können Sie Code für eine Anwendung schreiben, der für die auszuführende Aufgabe die höchste Effizienz aufweist.

Die GetRolesForUser-Methode greift immer auf den Anbieter zu. Ein Aufruf der IsInRole-Methode führt immer bei der ersten Anforderung einer Seite zu einem Aufruf der GetRolesForUser-Methode, wenn Cookiezwischenspeicherung nicht aktiviert ist. Bei aktivierter Cookiezwischenspeicherung werden für Aufrufe der IsInRole-Methode stattdessen die im Cookie zwischengespeicherten Rolleninformationen verwendet. Unabhängig davon, ob Cookiezwischenspeicherung aktiviert ist, führt der erste Aufruf der GetRoles-Methode zu einem Aufruf der GetRolesForUser-Methode. Jedoch werden bei anschließenden Aufrufen der GetRoles-Methode für eine Seite die im RolePrincipal zwischengespeicherten Rolleninformationen verwendet.

Hinweis:

Durch das Speichern vertraulicher Informationen in einem Cookie können diese Informationen für Benutzer verfügbar gemacht werden. Wenn Sie maximale Sicherheit benötigen, aktivieren Sie keine Cookiezwischenspeicherung.

Profileigenschaften

Wenn Code auf eine Profileigenschaft zugreift, liest der Profilanbieter beim Laden der Seite alle Profileigenschaften für den aktuellen Benutzer. (Der Anbieter liest alle Eigenschaften, die diesem Profilanbieter zugeordnet sind.) Bei einer Änderung eines Profileigenschaftenwerts werden die neuen Informationen in den Anbieterdatenspeicher zurückgeschrieben, wenn die Seite entladen wird. ASP.NET kann bestimmen, ob systeminterne Typen, z. B. ganze Zahlen und Zeichenfolgen, geändert wurden, jedoch kann ASP.NET nicht bestimmen, ob nicht systeminterne Typen geändert wurden.

Der Algorithmus, um zu bestimmen, ob Profileigenschaften gespeichert werden, lautet wie folgt:

  • Wenn alle Typen von Profileigenschaften systeminterne Typen sind und nicht geändert wurden, wird das Profil nicht in den Datenspeicher geschrieben.

  • Wenn alle Typen von Profileigenschaften systeminterne Typen sind und mindestens ein Typ geändert wurde, werden alle Profileigenschaftenwerte in den Datenspeicher geschrieben.

  • Wenn eine Eigenschaft kein systeminterner Typ ist, kann ASP.NET nicht bestimmen, ob ein Wert geändert wurde. Wenn auf die Eigenschaft in Code zugegriffen wird, wird der Eigenschaftenwert in den Datenspeicher geschrieben.

    Hinweis:

    In allen Fällen wird der Algorithmus auf alle Profileigenschaften für einen bestimmten Anbieter angewendet.

Wenn Sie nicht systeminterne Eigenschaftentypen verwenden, erfordert das Schreiben der Profildaten am Ende jeder Seitenanforderung eine bestimme Zeitspanne. Sie haben folgende Möglichkeiten, diesen Aufwand zu verringern:

  • Verwenden Sie in Profilen nur systeminterne Typen.

  • Legen Sie das automaticSaveEnabled-Attribut im <profile>-Konfigurationselement auf Off fest, und schreiben Sie stattdessen benutzerdefinierten Code, um Änderungen zu erkennen und ggf. Eigenschaftenwerte zu speichern.

  • Schreiben Sie benutzerdefinierten Code, um das ProfileAutoSaving-Ereignis zu behandeln, und bestimmen Sie im Ereigniscode, ob Profileigenschaften geändert wurden. Wenn keine Eigenschaften geändert wurden, brechen Sie den automatischen Speichervorgang ab, und legen Sie die ContinueWithProfileAutoSave-Eigenschaft des Ereignisses auf false fest.

Sitzungszustand

Bei Verwendung eines prozessexternen Sitzungszustandsmodus (weitere Informationen finden Sie unter Sitzungszustandsmodi) sind Leistungsaspekte zu berücksichtigen. Dieser Abschnitt enthält Informationen über das Optimieren der Leistung des Sitzungszustands.

Verringern des Aufwands beim Lesen und Schreiben des Sitzungszustands

Standardmäßig werden Sitzungszustandsinformationen bei jedem Laden der Seite geladen. Mit dem EnableSessionState-Attribut in der @ Page-Direktive können Sie das Laden des Sitzungszustands mit den folgenden Einstellungen steuern:

  • True   Sitzungszustandsdaten werden bei jedem Laden der Seite gelesen und gespeichert, wenn sie geändert wurden. ASP.NET kann bestimmen, ob systeminterne Typen, z. B. ganze Zahlen und Zeichenfolgen, geändert wurden. Wenn alle Sitzungszustandswerte systeminterne Typen sind und kein Wert geändert wurde, wird die Sitzung nicht gespeichert. Wenn einer der Werte kein systeminterner Typ ist und auf einen nicht systeminternen Sitzungswert zugegriffen wurde, werden alle Sitzungszustandsinformationen gespeichert. Dies geschieht, weil ASP.NET nicht nachverfolgt, ob nicht systeminterne Typen geändert wurden, und mit dem Speichern aller Daten die sicherste Option verwendet wird.

  • False   Sitzungszustandsdaten werden beim Laden der Seite nicht gelesen.

  • ReadOnly   Sitzungszustandsdaten werden bei jedem Laden der Seite gelesen, doch niemals gespeichert, selbst wenn Sitzungszustandswerte in Code geändert wurden.

Vermeiden von Sperrenkonflikten für den Sitzungszustand

Verwenden Sie keine <IFRAME>-Elemente auf Seiten, die einen Sitzungszustand erfordern. Wenn mehrere Anforderungen mit demselben Sitzungszustandsbezeichner an ASP.NET gesendet werden und alle Anforderungen für ASP.NET-Seiten erfolgen, für die EnableSessionState auf true festgelegt ist, konkurrieren die parallelen Anforderungen um die Sperre, die dem prozessexternen Sitzungszustand zugeordnet ist. Für <IFRAME>-Elemente bedeutet dies, dass ASP.NET-Seiten, die in mehreren <IFRAME>-Elementen auf einer Seite angezeigt werden, möglicherweise um dieselben Sitzungsdaten konkurrieren. Dies führt dazu, dass jede einzelne Anforderung auf dem Server serialisiert wird.

Webparts-Personalisierung

Wenn eine Seite ausgeführt wird, werden ASP.NET-Personalisierungsinformationen geladen. Um zu bestimmen, ob Webparts-Personalisierungsinformationen geändert wurden, ruft ASP.NET die Equals-Methode auf, um die alten und neuen Werte von Eigenschaften zu vergleichen, die mit dem PersonalizableAttribute-Attribut markiert sind.

Wenn ein Personalisierungseigenschaftenwert geändert wurde, werden die Personalisierungsdaten gespeichert. Für systeminterne Typen, z. B. ganze Zahlen, vergleicht die Equals-Methode die alten und neuen Eigenschaftenwerte direkt. Für nicht systeminterne Typen vergleicht ASP.NET jedoch den Wert des Verweises und nicht unbedingt die in einer Typinstanz gespeicherten Daten.

Beispielsweise vergleicht die Equals-Methode für eine Eigenschaft vom Typ ArrayList die alten und neuen Werte des ArrayList-Verweises, doch nicht den Inhalt des ArrayList-Objekts. Die Equals-Methode gibt true zurück, wenn der ArrayList-Verweis nicht geändert wurde, selbst wenn der Liste ein neues Element hinzugefügt wurde. In diesem Fall werden die ArrayList-Daten nicht gespeichert.

Dieser Algorithmus für nicht systeminterne Typen ist effizient, doch ist es falsch, die Daten nicht zu speichern. Wenn Sie die Daten eines nicht systeminternen Typs, z. B. eines ArrayList-Objekts, speichern möchten, legen Sie die IsDirty-Eigenschaft auf true fest, wenn das Steuerelement von WebPart abgeleitet wird, oder rufen Sie die SetPersonalizationDirty-Methode auf, die ein Steuerelement als Parameter akzeptiert.

Umfangreiche Siteübersichten führen zu einer geringeren Leistung als kleinere Siteübersichten. Beispielsweise kann sich in Testszenarios die Zeit zum Laden der Seite um ein Drittel verlängern, wenn die Anzahl der Knoten von 100 auf 1000 (eine zehnfache Erhöhung) erhöht wird.

Die Einschränkung aus Sicherheitsgründen, bei der Knoten anhand von Rollen gefiltert werden, führt zu einer stärkeren Leistungseinbuße als das Erhöhen der Anzahl von Knoten. Beispielsweise ist der Verarbeitungsaufwand einer Siteübersicht mit 1000 Knoten 10-mal höher als für eine Siteübersicht mit 100 Knoten.

Um diesen Effekt zu verringern, empfehlen sich z. B. folgende Maßnahmen:

  • Wenn die Einschränkung aus Sicherheitsgründen aktiviert ist, sollten maximal 150 Knoten verwendet werden.

  • Legen Sie in jedem Knoten der Siteübersicht das Roles-Attribut fest. Wenn das Roles-Attribut vorhanden ist, kann ASP.NET die URL- und Dateiautorisierung für den URL, der dem SiteMapNode zugeordnet ist, umgehen, solange ein Benutzer eine der im Attribut aufgelisteten Rollen innehat. Beachten Sie jedoch, dass ASP.NET wieder die langsameren Überprüfungen von Datei- und URL-Autorisierung ausführt, wenn ein Benutzer keine der angegebenen Rollen innehat.

  • Erstellen Sie eine Klasse, die von der SiteMapProvider-Klasse erbt, und überschreiben Sie die IsAccessibleToUser-Methode, um nur das Roles-Attribut in den einzelnen Knoten der Siteübersicht zu überprüfen. Hierdurch wird die Filterung beschleunigt, da URL- und Dateiautorisierung umgangen werden. Für diesen Ansatz sind jedoch zwei parallele Sicherheitsdefinitionen in der Webanwendung erforderlich. Bei der ersten Sicherheitsdefinition handelt es sich um die Autorisierungsinformationen in der Datei Web.config (und NTFS-Zugriffssteuerungslisten für die Dateiautorisierung, wenn Windows-Authentifizierung aktiviert ist). Bei der zweiten Sicherheitsdefinition handelt es sich um die Rolleninformationen in der Siteübersicht. Sie müssen den Aufwand für die Sicherheitsverwaltung durch Aufteilen der Sicherheitsinformationen gegen die Leistungsverbesserung bei der Siteübersichtsverarbeitung abwägen.

Weitere Informationen finden Sie unter Einschränken der ASP.NET-Siteübersicht aus Sicherheitsgründen und ASP.NET-Autorisierung.

Siehe auch

Konzepte

Sichern der ASP.NET-Sitenavigation

Übersicht über den ASP.NET-Sitzungszustand