Freigeben über


Entwickeln von leistungsfähigen ASP.NET-Anwendungen

In den Richtlinien dieses Themas sind Techniken aufgeführt, mit denen Sie den Durchsatz von ASP.NET-Webanwendungen steigern können. Die Richtlinien sind in folgende Abschnitte unterteilt:

  • Verarbeitung von Seiten und Serversteuerelementen

  • Zustandsverwaltung

  • Datenzugriff

  • Webanwendungen

  • Codierungstechniken

Verarbeitung von Seiten und Serversteuerelementen

In den folgenden Richtlinien werden Möglichkeiten präsentiert, die Arbeit mit ASP.NET-Seiten und -Steuerelementen besonders effizient zu gestalten.

  • Vermeiden Sie unnötige Roundtrips zum Server: Unter bestimmten Umständen ist die Verwendung von ASP.NET-Serversteuerelementen und die Behandlung von Postbackereignissen unnötig. So können Benutzereingaben in ASP.NET-Webseiten beispielsweise oftmals auf dem Client validiert werden, bevor die Daten an den Server gesendet werden. Grundsätzlich gilt: Sofern Sie keine Informationen an den Server weiterleiten müssen, um sie zu überprüfen oder in einen Datenspeicher zu schreiben, können Sie Leistung und Benutzfreundlichkeit der Seite verbessern, indem Sie auf Code verzichten, der einen Roundtrip zum Server verursacht. Anstatt einen vollständigen Roundtrip durchzuführen, können Sie auch Clientrückrufe verwenden, um Daten vom Server zu lesen. Ausführliche Informationen finden Sie unter Implementieren von Clientrückrufen ohne Postbacks in ASP.NET-Webseiten.

    Bei der Entwicklung benutzerdefinierter Serversteuerelemente sollten Sie in Betracht ziehen, von den Steuerelementen clientseitigen Code für Browser rendern zu lassen, die ECMAScript (JavaScript) unterstützen. Indem Sie Serversteuerelemente auf diese Weise verwenden, lässt sich die Häufigkeit, mit der Informationen unnötigerweise an den Webserver gesendet werden, erheblich reduzieren. Weitere Informationen finden Sie unter Entwickeln von benutzerdefinierten ASP.NET-Serversteuerelementen.

  • Verwenden Sie die IsPostBack-Eigenschaft der Seite, um die unnötige Verarbeitung bei einem Roundtrip zu vermeiden: Wenn Sie Code für die Postbackverarbeitung von Serversteuerelementen schreiben, möchten Sie Code möglicherweise nicht bei jedem Postback, sondern nur bei der ersten Seitenanforderung ausführen lassen. Verwenden Sie die IsPostBack-Eigenschaft, um Code bedingt auszuführen, und zwar abhängig davon, ob die Seite als Reaktion auf ein Serversteuerelement-Ereignis generiert wird.

  • Speichern Sie den Ansichtszustand von Serversteuerelementen nur, wenn dies notwendig ist: Die automatische Verwaltung des Ansichtszustands ermöglicht das Wiederauffüllen der Eigenschaftenwerte von Serversteuerelementen bei einem Roundtrip, ohne dass Sie dafür Code schreiben müssen. Dieses Feature beeinträchtigt jedoch die Leistung, da der Ansichtszustand eines Serversteuerelements in einem ausgeblendeten Formularfeld vom Server empfangen und gesendet wird. Es ist hilfreich zu wissen, wann der Ansichtszustand von Nutzen ist und wann er die Seitenleistung mindert. Wenn Sie beispielsweise ein Serversteuerelement bei jedem Roundtrip an Daten binden, bringt der gespeicherte Ansichtszustand keinen Nutzen, da die Werte des Steuerelements während der Datenbindung mit neuen Werten ersetzt werden. In diesem Fall wird durch Deaktivieren des Ansichtszustands Verarbeitungszeit gespart und die Größe der Seite reduziert.

    Der Ansichtszustand ist für alle Serversteuerelemente standardmäßig aktiviert. Um ihn zu deaktivieren, legen Sie die EnableViewState-Eigenschaft des Steuerelements auf false fest, wie im folgenden Beispiel für ein DataGrid-Serversteuerelement gezeigt:

    <asp:datagrid EnableViewState="false" datasource="..." 
       runat="server"/>
    

    Mithilfe der @ Page-Direktive kann der Ansichtszustand auch für eine komplette Seite deaktiviert werden. Dies ist hilfreich, wenn keine Postbacks von einer Seite zum Server erfolgen:

    <%@ Page EnableViewState="false" %>
    

    Hinweis

    Das EnableViewState-Attribut wird auch in der @ Control-Direktive unterstützt, und Sie können mit ihm festlegen, ob der Ansichtszustand für ein Benutzersteuerelement aktiviert ist.

    Um die Größe des Ansichtszustands festzustellen, der von den Serversteuerelementen auf der Seite verwendet wird, aktivieren Sie die Ablaufverfolgung der Seite, indem Sie das trace="true"-Attribut in die @ Page-Direktive einschließen. Das Ergebnis finden Sie in der Ablaufverfolgungsausgabe in der Tabelle Steuerungshierarchie in der Spalte Ansichtszustand. Weitere Informationen über die Ablaufverfolgung und ihre Aktivierung finden Sie unter ASP.NET-Ablaufverfolgung.

  • Lassen Sie die Pufferung aktiviert, sofern es keinen bestimmten Grund gibt, sie zu deaktivieren: Die Leistung von ASP.NET-Webseiten wird durch das Deaktivieren der Pufferung erheblich beeinträchtigt. Weitere Informationen finden Sie in den Ausführungen zur Buffer-Eigenschaft.

  • Verwenden Sie die Transfer -Methode des Server -Objekts oder das seitenübergreifende Senden von Daten, um Umleitungen zwischen ASP.NET-Seiten derselben Anwendung herzustellen: Ausführliche Informationen zu diesem Thema finden Sie unter Umleiten von Benutzern auf eine andere Seite.

Zustandsverwaltung

In den folgenden Richtlinien werden Möglichkeiten vorgeschlagen, die Zustandsverwaltung effizient zu gestalten.

  • Deaktivieren Sie den Sitzungszustand, falls er nicht verwendet wird: Da nicht alle Anwendungen oder Seiten Sitzungszustandsdaten pro Benutzer erfordern, können Sie den Sitzungszustand womöglich deaktivieren. Um den Sitzungszustand für eine Seite zu deaktivieren, legen Sie das EnableSessionState-Attribut in der @ Page-Direktive auf false fest, wie im folgenden Beispiel gezeigt:

    <%@ Page EnableSessionState="false" %>
    

    Hinweis

    Wenn eine Seite Zugriff auf Sitzungsvariablen benötigt, diese aber nicht erstellen oder ändern muss, legen Sie das EnableSessionState-Attribut in der @ Page-Direktive auf ReadOnly fest.

    Der Sitzungszustand kann auch für XML-Webdienstmethoden deaktiviert werden. Weitere Informationen finden Sie unter Mithilfe von ASP.NET und XML-Webdienstclients erstellte XML-Webdienste.

    Um den Sitzungszustand für eine Anwendung zu deaktivieren, legen Sie im SessionState-Abschnitt der Datei Web.config der Anwendung das Mode-Attribut auf Off fest, wie im folgenden Beispiel gezeigt:

    <sessionState mode="Off" />
    
  • Wählen Sie den Sitzungszustandsanbieter den Erfordernissen Ihrer Anwendung entsprechend aus   ASP.NET bietet verschiedene Möglichkeiten, die Sitzungsdaten Ihrer Anwendung zu speichern: prozessinterner Sitzungszustand, prozessexterner Sitzungszustand als Windows-Dienst und prozessexterner Sitzungszustand in einer SQL Server-Datenbank. (Sie können auch einen benutzerdefinierten Sitzungszustandsanbieter erstellen, um Sitzungsdaten in einem Datenspeicher Ihrer Wahl zu speichern.) Obwohl jede Lösung ihre Vorteile hat, bietet der prozessinterne Sitzungszustand mit Abstand die höchste Geschwindigkeit. Wenn lediglich geringe Mengen flüchtiger Daten im Sitzungszustand gespeichert werden, wird die Verwendung des prozessinternen Anbieters empfohlen. Prozessexterne Sitzungszustandsoptionen sind nützlich, wenn die Anwendung auf mehrere Prozessoren oder Computer skaliert wird oder wenn Sie Sitzungsdaten bei einem Neustart eines Servers oder Prozesses beibehalten möchten. Weitere Informationen finden Sie unter ASP.NET-Sitzungszustand.

Datenzugriff

In den folgenden Richtlinien werden Möglichkeiten vorgeschlagen, den Datenzugriff in der Anwendung effizient zu gestalten.

  • Verwenden Sie SQL Server und gespeicherte Prozeduren für den Datenzugriff: Unter allen Datenzugriffsmethoden, die von .NET Framework bereitgestellt werden, wird der Datenzugriff mit SQL Server als bevorzugte Methode für die Entwicklung von besonders leistungsfähigen, skalierbaren Webanwendungen empfohlen. Bei Verwendung des verwalteten Anbieters für SQL Server sollten Sie nach Möglichkeit kompilierte gespeicherte Prozeduren anstelle von SQL-Befehlen verwenden. Die Leistungssteigerung ist immens. Informationen zur Verwendung von gespeicherten Prozeduren von SQL Server finden Sie unter Verwenden von gespeicherten Prozeduren mit einem Befehl.

  • Verwenden Sie die SqlDataReader-Klasse als schnellen Vorwärtsdatencursor: Die SqlDataReader-Klasse bietet einen Vorwärtsdatenstream, der aus einer SQL Server-Datenbank abgerufen wird. Wenn Sie in der ASP.NET-Anwendung einen schreibgeschützten Stream verwenden können, bietet die SqlDataReader-Klasse eine höhere Leistung als die DataSet-Klasse. Die SqlDataReader-Klasse verwendet das systemeigene SQL Server-Format für die Netzwerkdatenübertragung, um Daten direkt über eine Datenbankverbindung zu lesen. Beispielsweise wird beim Binden an das SqlDataSource-Steuerelement die Leistung verbessert, indem die DataSourceMode-Eigenschaft auf DataReader festgelegt wird. (Bei Verwendung eines Datenreaders geht einige Funktionalität verloren.) Außerdem implementiert die SqlDataReader-Klasse die IEnumerable-Schnittstelle, mit deren Hilfe Daten auch an Serversteuerelemente gebunden werden können. Weitere Informationen finden Sie in den Ausführungen zur SqlDataReader-Klasse. Informationen dazu, wie der Datenzugriff durch ASP.NET erfolgt, finden Sie unter Zugreifen auf Daten mit ASP.NET.

  • Daten und Seitenausgaben sollten, falls möglich, zwischengespeichert werden.: ASP.NET stellt Mechanismen zum Zwischenspeichern von Seitenausgaben oder Daten bereit, wenn diese nicht dynamisch für jede Seitenanforderung berechnet werden müssen. Darüber hinaus kann der Entwurf von Seiten und Datenanforderungen, die zwischengespeichert werden, insbesondere in Sitebereichen mit hohem Netzwerkdatenverkehr die Leistung dieser Seiten verbessern. Die richtige Verwendung des Zwischenspeichers kann mehr als alle anderen .NET Framework-Features zur Leistungsoptimierung einer Site beitragen.

    Beachten Sie bei der Verwendung von ASP.NET-Zwischenspeicherung Folgendes. Erstens: Speichern Sie nicht zu viele Elemente zwischen. Das Zwischenspeichern jedes Elements ist mit Speicherbedarf verbunden. Elemente, die auf einfache Weise neu berechnet werden können oder die selten verwendet werden, sollten nicht zwischengespeichert werden. Zweitens: Weisen Sie zwischengespeicherten Elementen keine kurze Ablaufzeit zu. Elemente mit kurzer Ablaufzeit verursachen eine unnötige Belastung durch hohes Turnover im Cache und können einen höheren Arbeitsaufwand für den Bereinigungscode und den Garbage Collector zur Folge haben. Das durch ablaufende Elemente verursachte Turnover im Cache kann mit dem Leistungsindikator Gesamte Cachturnoverrate überwacht werden, der dem Leistungsobjekt ASP.NET-Anwendungen zugeordnet ist. Eine hohe Turnoverrate weist u. U. auf ein Problem hin, besonders wenn Elemente entfernt werden, bevor sie abgelaufen sind. (Dies wird gelegentlich auch als Speicherdruck bezeichnet.)

    Informationen zum Zwischenspeichern von Seitenausgaben und Datenanforderungen finden Sie unter Übersicht über das Zwischenspeichern in ASP.NET.

  • Verwenden Sie SQL-Cacheabhängigkeit bedarfsgerecht: ASP.NET unterstützt je nach verwendeter Version von SQL Server sowohl tabellenbasierte Abrufe als auch Abfragebenachrichtigungen. Tabellenbasierte Abrufe werden von allen Versionen von SQL Server unterstützt. Bei tabellenbasiertem Abruf werden alle Listener ungültig, wenn eine Änderung in der Tabelle erfolgt. Dies kann zu einer unnötig hohen Anzahl von Änderungen in der Anwendung führen. Tabellenbasierte Abrufe sollten nicht für Tabellen verwendet werden, an denen häufig viele Änderungen vorgenommen werden. Beispielsweise empfehlen sich tabellenbasierte Abrufe für eine Katalogtabelle, die selten geändert wird. Sie empfehlen sich nicht für eine Bestellungstabelle, die häufiger aktualisiert wird. Die Abfragebenachrichtigung wird von SQL Server 2005 unterstützt. Die Abfragebenachrichtigung erfolgt für spezielle Abfragen, sodass sich die Anzahl der Benachrichtigungen verringert, die bei Änderungen von Tabellen gesendet werden. Dieses Feature kann zwar eine bessere Leistung als tabellenbasierte Abfragen ermöglichen, ist jedoch nicht für Tausende von Abfragen geeignet.

    Weitere Informationen über SQL-Cacheabhängigkeit finden Sie unter Exemplarische Vorgehensweise: Verwenden der ASP.NET-Ausgabecachefunktion mit SQL Server und unter Zwischenspeichern in ASP.NET mithilfe der SqlCacheDependency-Klasse.

  • Verwenden Sie Datenquellenpaging und -sortierung anstelle von Benutzeroberflächenpaging und -sortierung: Das Feature Benutzeroberflächenpaging von Datensteuerelementen, z. B. von DetailsView und GridView, kann für jedes Datenquellenobjekt verwendet werden, das die ICollection-Schnittstelle unterstützt. Das Datensteuerelement fragt für jeden Pagingvorgang die gesamte Datenauflistung von der Datenquelle ab, wählt die anzuzeigenden Zeilen aus und verwirft die restlichen Daten. Wenn eine Datenquelle DataSourceView implementiert und die CanPage-Eigenschaft true zurückgibt, verwendet das Datensteuerelement Datenquellenpaging anstelle von Benutzeroberflächenpaging. In diesem Fall fragt das Datensteuerelement nur die für jeden Pagingvorgang erforderliche Zeile ab. Daher ist Datenquellenpaging effizienter als Benutzeroberflächenpaging. Datenquellenpaging wird nur vom ObjectDataSource-Datenquellensteuerelement unterstützt. Um Datenquellenpaging für andere Datenquellensteuerelemente zu aktivieren, müssen Sie das Datenquellensteuerelement vererben und sein Verhalten ändern.

  • Wägen Sie den Sicherheitsgewinn durch Ereignisvalidierung gegen die resultierende Leistungseinbuße ab: Steuerelemente, die von der System.Web.UI.WebControls-Klasse und der System.Web.UI.HtmlControls-Klasse abgeleitet werden, können überprüfen, ob ein Ereignis von der Benutzeroberfläche stammt, die vom Steuerelement gerendert wurde. Dies hilft zu verhindern, dass das Steuerelement auf eine vorgetäuschte Ereignisbenachrichtigung reagiert. Beispielsweise kann das DetailsView-Steuerelement verhindern, dass ein Delete-Aufruf (der im Steuerelement nicht grundsätzlich unterstützt wird) verarbeitet wird und Daten aufgrund einer Manipulation gelöscht werden. Diese Validierung führt zu einer Leistungseinbuße. Sie können dieses Verhalten mit dem EnableEventValidation-Konfigurationselement und der RegisterForEventValidation-Methode steuern. Die Leistungseinbuße durch Validierung hängt von der Anzahl der Steuerelemente auf der Seite ab und liegt im Bereich von einigen Prozent.

    Security noteSicherheitshinweis Hinweis

    Es wird dringend davon abgeraten, die Ereignisvalidierung zu deaktivieren. Bevor Sie die Ereignisvalidierung deaktivieren, müssen Sie davon überzeugt sein, dass kein Postback erzeugt werden kann, das unerwünschte Auswirkungen auf die Anwendung hat.

  • Verschlüsseln Sie den Ansichtszustand nur, wenn dies erforderlich ist: Die Verschlüsselung des Ansichtszustands verhindert, dass Benutzer Werte im ausgeblendeten Ansichtszustandsfeld lesen können. Ein typisches Szenario ist ein GridView-Steuerelement, das in der DataKeyNames-Eigenschaft ein Bezeichnerfeld enthält. Das Bezeichnerfeld ist erforderlich, um Aktualisierungen von Datensätzen zu koordinieren. Da der Bezeichner für Benutzer nicht sichtbar sein soll, können Sie den Ansichtszustand verschlüsseln. Die Verschlüsselung führt jedoch zu einer konstanten Leistungseinbuße für die Initialisierung und zu weiteren Leistungseinbußen, die vom Umfang des verschlüsselten Ansichtszustand abhängen. Die Verschlüsselung wird für jedes Laden der Seite eingerichtet. Daher tritt bei jedem Laden der Seite dieselbe Leistungseinbuße auf.

  • Verwenden Sie Zwischenspeicherung, Sortierung und Filterung mit SqlDataSource: Wenn die DataSourceMode-Eigenschaft des SqlDataSource-Steuerelements auf DataSet festgelegt ist, kann die SqlDataSource das Resultset aus einer Abfrage zwischenspeichern. Bei dieser Art der Zwischenspeicherung werden für die Filter- und Sortiervorgänge des Steuerelements (mit der FilterExpression-Eigenschaft und der SortParameterName-Eigenschaft konfiguriert) die zwischengespeicherten Daten verwendet. Häufig wird die Anwendung schneller ausgeführt, wenn Sie das gesamte Dataset zwischenspeichern und zum Filtern und Sortieren anstelle von SQL-Abfragen mit WHERE-Klauseln und SORT-BY-Klauseln, die für jeden Auswahlvorgang auf die Datenbank zugreifen, die FilterExpression-Eigenschaft bzw. die SortParameterName-Eigenschaft verwenden.

Webanwendungen

In den folgenden Richtlinien werden Möglichkeiten vorgeschlagen, die Webanwendungen insgesamt effizienter zu machen.

  • Ziehen Sie eine Vorkompilierung in Betracht   Eine Webanwendung wird bei der ersten Anfrage für eine Ressource, z. B. eine ASP.NET-Webseite, per Batch kompiliert. Wenn keine Seite in der Anwendung kompiliert wurde, werden bei der Batchkompilierung alle Seiten in einem Verzeichnis in Segmente kompiliert, um die Datenträger- und Speicherauslastung zu optimieren. Sie können das ASP.NET-Kompilierungstool (Aspnet_compiler.exe) verwenden, um eine Webanwendung vorzukompilieren. Bei einer direkten Kompilierung ruft das Kompilierungstool die ASP.NET-Laufzeit auf, um die Website auf die gleiche Weise zu kompilieren wie bei einer Anforderung eines Benutzers von der Website aus. Sie können eine Webanwendung vorkompilieren, damit das UI-Markup beibehalten wird, oder Sie können die Seiten vorkompilieren, damit der Quellcode nicht geändert werden kann. Weitere Informationen finden Sie unter How to: Precompile ASP.NET Web SitesGewusst wie: Vorkompilieren von ASP.NET-Websites.

  • Führen Sie Webanwendungen in Internetinformationsdienste 5.0 prozessextern aus: ASP.NET verarbeitet in IIS 5.0 Anforderungen standardmäßig mit einem prozessexternen Workerprozess. Dieses Feature wurde auf einen schnellen Durchsatz abgestimmt. Aufgrund der zahlreichen Features und Vorteile wird die Ausführung von ASP.NET in einem prozessexternen Workerprozess für Produktionssites empfohlen.

  • Verwenden Sie Prozesse regelmäßig wieder: Aus Gründen der Stabilität und Leistung sollten Sie Prozesse regelmäßig wiederverwenden. Über längere Zeiträume hinweg können mit Fehlern behaftete und Speicherverlust verursachende Ressourcen den Durchsatz des Webservers beeinträchtigen. Durch die Wiederverwendung von Prozessen wird bei derartigen Problemen der Speicher bereinigt. Allerdings muss beachtet werden, dass eine zu häufige Wiederverwendung von Prozessen auch Nachteile bergen kann, wenn der Aufwand für das Unterbrechen von Workerprozessen, das erneute Laden von Seiten und das erneute Abrufen von Ressourcen und Daten die Vorteile der Wiederverwendung überwiegt.

    Bei ASP.NET-Anwendungen, die unter Windows Server 2003 und IIS 6.0 ausgeführt werden, muss die Prozessmodelleinstellung nicht angepasst werden, da ASP.NET die Prozessmodelleinstellungen von IIS 6.0 verwendet.

  • Passen Sie bei Bedarf die Anzahl von Threads pro Workerprozess an die Anwendung an: Die Anforderungsarchitektur von ASP.NET versucht, einen Ausgleich zwischen den verfügbaren Ressourcen und den Threads herzustellen, die die Anforderungen ausführen. Die Architektur lässt nur so viele gleichzeitig ausgeführte Anforderungen zu, wie von der verfügbaren CPU-Leistung verarbeitet werden können. Diese Technik wird als Threadgating bezeichnet. Unter bestimmten Bedingungen funktioniert der Threadgating-Algorithmus jedoch nur eingeschränkt. Zum Überwachen des Threadgating im Windows-Systemmonitor kann der Leistungsindikator Pipeline-Instanzenzahl verwendet werden, der dem Leistungsobjekt ASP.NET-Anwendungen zugeordnet ist.

    Wenn eine ASP.NET-Webseite eine externe Ressource aufruft, z. B. bei der Durchführung von Datenbankzugriffen oder XML-Webdienstanforderungen, wird die Seitenanforderung im Allgemeinen bis zur Beantwortung durch die externe Ressource unterbrochen und damit die CPU für die Verarbeitung anderer Threads freigegeben. Sofern eine weitere Anforderung auf ihre Verarbeitung wartet und ein Thread im Threadpool frei ist, wird die wartende Anforderung verarbeitet. Dies kann zu einer großen Anzahl gleichzeitig ausgeführter Anforderungen und wartender Threads im ASP.NET-Workerprozess oder im Anwendungspool führen und damit den Durchsatz des Webservers einschränken und die Leistung nachteilig beeinflussen.

    Um diesen Effekt abzuschwächen, können Sie die Anzahl der Threads im Prozess manuell begrenzen, indem Sie im processModel-Abschnitt der Datei Machine.config das MaxWorkerThreads-Attribut und das MaxIOThreads-Attribut ändern.

    Hinweis

    Mit Arbeitsthreads werden ASP.NET-Anforderungen verarbeitet, während mit E/A-Threads Daten aus Dateien, Datenbanken oder XML-Webdiensten bedient werden.

    Die diesen Prozessmodellattributen zugewiesenen Werte geben die maximale Anzahl des jeweiligen Threadtyps pro CPU im Prozess an. Bei einem Computer mit zwei Prozessoren ist die maximale Anzahl doppelt so hoch wie der festgelegte Wert. Für Computer mit vier Prozessoren wird der festgelegte Wert vervierfacht. Die Standardwerte eignen sich für Computer mit einem oder zwei Prozessoren, aber eine Anzahl von 100 oder 200 Threads im Prozess wirkt sich bei Computern mit mehr Prozessoren möglicherweise eher negativ als positiv auf die Leistung aus. Wenn sich zu viele Threads in einem Prozess befinden, verringert sich aufgrund der zusätzlichen Kontextwechsel oftmals die Servergeschwindigkeit, denn das Betriebssystem muss CPU-Zyklen zum Verwalten von Threads aufwenden und nicht zum Bearbeiten von Anforderungen. Die geeignete Anzahl an Threads kann am besten durch Leistungstests mit der Anwendung bestimmt werden.

  • Ziehen Sie bei Anwendungen, die extrem auf externe Ressourcen angewiesen sind, die Verwendung eines Webgartens auf Multiprozessorcomputern in Betracht: Das ASP.NET-Prozessmodell unterstützt die Skalierbarkeit auf Multiprozessorcomputern, indem die Arbeitslast auf mehrere Prozesse (einen pro CPU) verteilt und die Prozessorzugehörigkeit auf die jeweilige CPU festgelegt wird. Diese Technik wird als "Webgardening" bezeichnet. Wenn die Anwendung einen langsamen Datenbankserver verwendet oder COM-Objekte mit externen Abhängigkeiten aufruft – um nur zwei Möglichkeiten zu nennen – kann sich die Verwendung eines Webgartens vorteilhaft auf die Anwendung auswirken. Sie sollten jedoch die Anwendungsleistung in einem Webgarten testen, bevor Sie diese Lösung auf einer Produktionswebsite einsetzen.

  • Deaktivieren Sie den Debugmodus: Deaktivieren Sie immer den Debugmodus, bevor Sie eine Produktionsanwendung bereitstellen oder Leistungstests durchführen. Bei aktiviertem Debugmodus kann die Anwendungsleistung gemindert werden. Informationen über die Syntax zum Einstellen des Debugmodus finden Sie unter Bearbeiten von ASP.NET-Konfigurationsdateien.

  • Passen Sie die Konfigurationsdateien Ihren Anforderungen entsprechend an den Webservercomputer und die jeweiligen Anwendungen an: In der Standardeinstellung ist die ASP.NET-Konfiguration so festgelegt, dass die meisten Features aktiviert sind und die gängigsten Szenarios unterstützt werden. Einige Standardkonfigurationseinstellungen können geändert werden, um die Leistung der Anwendungen zu verbessern. Ob dies empfehlenswert ist, hängt von den verwendeten Features ab. In der folgenden Auflistung sind Konfigurationseinstellungen aufgeführt, die Sie in Betracht ziehen sollten:

    • Aktivieren Sie die Authentifizierung nur für Anwendungen, die sie benötigen: Standardmäßig ist der Authentifizierungsmodus für ASP.NET-Anwendungen Windows bzw. integriertes NTLM. In den meisten Fällen empfiehlt es sich, die Authentifizierung in der Datei Machine.config zu deaktivieren und sie in den Dateien Web.config für die Anwendungen zu aktivieren, für die sie erforderlich ist.

    • Konfigurieren Sie die Anwendung so, dass sie mit den entsprechenden Einstellungen für die Anforderungs- und Antwortcodierung übereinstimmt: Die Standardcodierung von ASP.NET ist UTF-8. Wenn die Anwendung ausschließlich ASCII unterstützt, können Sie die Anwendung für ASCII konfigurieren, um eine geringfügige Leistungssteigerung zu erzielen.

    • Erwägen Sie, AutoEventWireup für die Anwendung zu deaktivieren: Wenn das AutoEventWireup-Attribut in der Datei Machine.config auf false festgelegt wird, werden die Seitenereignisse nicht anhand von Namensübereinstimmungen an Methoden gebunden (z. B. Page_Load). Wenn Sie AutoEventWireup deaktivieren, erreichen Sie eine leichte Leistungsverbesserung für die Seiten, da die Ereignisverknüpfung Ihnen überlassen bleibt und nicht automatisch ausgeführt wird.

      Wenn Sie Seitenereignisse behandeln möchten, verwenden Sie eine von zwei Strategien. Die erste Strategie besteht im Überschreiben der Methoden in der Basisklasse. Sie können z. B. die OnLoad-Methode des Page-Objekts für das Ladeereignis der Seite überschreiben, statt eine Page_Load-Methode zu verwenden. (Sie müssen die Basismethode aufrufen, um sicherzustellen, dass alle Ereignisse ausgelöst werden.) Die zweite Strategie besteht im Binden an die Ereignisse mithilfe des Handles-Schlüsselworts in Visual Basic oder der Delegatverknüpfung in C#.

    • Entfernen Sie nicht verwendete Module aus der Pipeline für die Anforderungsverarbeitung: Standardmäßig sind alle Features im Knoten HttpModules in der Datei Machine.config für den Servercomputer aktiviert. Abhängig von den für Ihre Anwendung verwendeten Features, können Sie möglicherweise die nicht verwendeten Module aus der Anforderungspipeline entfernen, um eine kleine Leistungsverbesserung zu erzielen. Überprüfen Sie jedes Modul und seine Funktionen, und passen Sie es an die Erfordernisse an. Wenn Sie beispielsweise in einer Anwendung weder den Sitzungszustand noch den Ausgabecache verwenden, können Sie die beiden zugehörigen Module aus der HttpModules-Liste entfernen. Bei Anforderungen müssen diese Module dann nicht aufgerufen werden, und die Verarbeitungskapazität kann sinnvoll eingesetzt werden.

Codierungstechniken

In den folgenden Richtlinien werden Möglichkeiten vorgeschlagen, wie das Schreiben von Code effizienter gestaltet werden kann.

  • Verwenden Sie möglichst keine Ausnahmen im Code: Da Ausnahmen zu erheblichen Leistungseinbußen führen, sollte die Steuerung des normalen Programmflusses ohne Ausnahmen auskommen. Falls im Code eine Bedingung ermittelt werden kann, die zu einer Ausnahme führen würde, ist dies dem Abfangen der Ausnahme selbst und dem Behandeln der Bedingung vorzuziehen. Zu den gängigen Szenarios, bei denen die Ermittlung im Code erfolgt, gehören: das Suchen von null, das Zuweisen eines Werts zu String, wenn dieser Wert dann durch Analyse in einen numerischen Wert konvertiert wird, oder das Suchen spezifischer Werte vor der Anwendung mathematischer Operationen. Das folgende Beispiel enthält Code, der eine Ausnahme auslösen könnte, sowie Code zum Testen einer Bedingung. In beiden Fällen wird dasselbe Ergebnis ausgegeben.

    // This is not recommended.
    try {
       result = 100 / num;
    }
    catch (Exception e) {
      result = 0;
    }
    
    // This is preferred.
    if (num != 0)
       result = 100 / num;
    else
      result = 0;
    
    ' This is not recommended.
    Try
       result = 100 / num
    Catch (e As Exception)
      result = 0
    End Try
    
    ' This is preferred.
    If Not (num = 0)
       result = 100 / num
    Else
      result = 0
    End If
    
  • Schreiben Sie aufrufintensive COM-Komponenten in verwalteten Code um: .NET Framework bietet eine einfache Möglichkeit zur Interoperation mit herkömmlichen COM-Komponenten. Der Vorteil liegt darin, dass Sie die Vorteile von .NET nutzen können und gleichzeitig Ihre vorhandenen Investitionen in COM-Komponenten erhalten. Unter bestimmten Umständen fällt der Leistungsverlust durch Beibehaltung alter Komponenten jedoch so stark ins Gewicht, dass die Migration der Komponenten in verwalteten Code sich auszahlt. Da jede Situation anders ist, sollte die Website am besten mithilfe der entsprechenden Leistungsbemessungen getestet werden, um zu entscheiden, ob eine Komponente portiert werden sollte. Überprüfen Sie für alle häufig aufgerufenen COM-Komponenten, ob eine Portierung in verwalteten Code sinnvoll ist.

    In vielen Fällen ist es nicht möglich, ältere Komponenten in verwalteten Code zu migrieren, besonders beim ersten Migrieren der Webanwendungen. Unter diesen Umständen stellt das Marshalling von Daten aus unverwalteten in verwaltete Umgebungen eines der größten Leistungshindernisse dar. Führen Sie daher bei der Interoperation beider Umgebungen so viele Aufgaben wie möglich auf der einen oder auf der anderen Seite aus. Es ist ratsamer, dann einen einzigen Aufruf anstelle einer Reihe von kleineren Aufrufen durchzuführen. Beispielsweise sind alle Zeichenfolgen in der Common Language Runtime in Unicode, daher sollten alle Zeichenfolgen in einer Komponente in Unicode konvertiert werden, bevor Sie den verwalteten Code aufrufen.

    Geben Sie alle COM-Objekte oder systemeigenen Ressourcen frei, sobald ihre Verarbeitung beendet ist. So können sie von anderen Anforderungen verwendet werden, und die Leistungsprobleme, die auftreten, wenn der Garbage Collector sie später freigeben muss, werden minimiert.

  • Vermeiden Sie STA-COM-Komponenten (Singlethread-Apartment): In der Standardeinstellung lässt ASP.NET nicht zu, dass STA-COM-Komponenten in einer Seite ausgeführt werden. Um diese Komponenten auszuführen, muss das ASPCompat=true-Attribut in die @ Page-Direktive der ASPX-Datei eingeschlossen werden. Dadurch wird der für die Seitenausführung verwendete Threadpool in einen STA-Threadpool geändert, und gleichzeitig werden dem COM-Objekt auch der HttpContext und andere integrierte Objekte zur Verfügung gestellt. Das Vermeiden von STA-COM-Komponenten sorgt für eine Leistungsoptimierung, da dadurch das Marshalling von Aufrufen aus MTA-Threads (Multithread-Apartment) in STA-Threads verhindert wird.

    Wenn Sie eine STA-COM-Komponente verwenden müssen, sollten Sie das Durchführen von vielen Aufrufen bei der Ausführung vermeiden und versuchen, bei jedem Aufruf so viele Informationen wie möglich zu übermitteln. Vermeiden Sie außerdem das Erstellen von STA-COM-Komponenten während der Konstruktion der Seite. Im folgenden Code wird z. B. SampleSTAComponent zum Zeitpunkt der Konstruktion der Seite instanziiert, und diese wird aus einem Thread erstellt, bei dem es sich nicht um den STA-Thread handelt, der die Seite ausführt. Dies kann zu Leistungsbeeinträchtigungen führen, da zum Konstruieren der Seite ein Marshalling zwischen MTA- und STA-Threads ausgeführt werden muss.

    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp as new SampleSTAComponent()
    Public Sub Page_Load()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>
    

    Vorzuziehen ist ein Mechanismus, bei dem die Objekterstellung verschoben wird, bis der Code unter einem STA-Thread ausgeführt wird. Dies wird im folgenden Beispiel veranschaulicht:

    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp
    Public Sub Page_Load()
        myComp = new SampleSTAComponent()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>
    

    Es wird empfohlen, COM-Komponenten und externe Ressourcen erst bei Bedarf oder in der Page_Load-Methode zu erstellen.

    STA-COM-Komponenten sollten niemals in einer freigegebenen Ressource (wie dem Cache oder dem Sitzungszustand) gespeichert werden, wo außer dem Thread, von dem sie erstellt wurden, auch noch andere Threads auf sie zugreifen können. Auch wenn ein STA-Thread eine STA-COM-Komponente aufruft, kann nur der Thread den Aufruf bedienen, der die STA-COM-Komponente erstellt hat. Daraus ergibt sich als logische Folge, dass der Aufruf an den erstellenden Thread gemarshallt wird. Durch dieses Marshalling können signifikante Leistungseinbußen und Skalierbarkeitsprobleme auftreten. In solchen Fällen sollten Sie in Betracht ziehen, die COM-Komponente in eine MTA-COM-Komponente umzuwandeln oder die Komponente in verwalteten Code umzuschreiben.

Siehe auch

Konzepte

Leistungsoptimierung in ASP.NET
Überwachen der ASP.NET-Anwendungsleistung
Leistungsindikatoren für ASP.NET

Weitere Ressourcen

ASP.NET-Zwischenspeicherung