Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Zeitspanne, die für den Start einer WPF-Anwendung erforderlich ist, kann stark variieren. In diesem Thema werden verschiedene Techniken zum Verringern der wahrgenommenen und tatsächlichen Startzeit für eine Windows Presentation Foundation (WPF)-Anwendung beschrieben.
Grundlegendes zu Kaltstart und Warmstart
Kaltstart tritt auf, wenn die Anwendung nach einem Systemneustart zum ersten Mal gestartet wird, oder wenn Sie die Anwendung starten, schließen Sie sie, und starten Sie sie dann nach langer Zeit erneut. Wenn eine Anwendung gestartet wird, wenn die erforderlichen Seiten (Code, statische Daten, Registrierung usw.) nicht in der Standbyliste des Windows-Speicher-Managers vorhanden sind, treten Seitenfehler auf. Der Datenträgerzugriff ist erforderlich, um die Seiten in den Arbeitsspeicher zu bringen.
Der warme Start tritt auf, wenn die meisten Seiten für die Hauptkomponenten für die Common Language Runtime (CLR) bereits im Arbeitsspeicher geladen sind, wodurch teure Festplattenzugriffszeiten gespart werden. Aus diesem Grund wird eine verwaltete Anwendung schneller gestartet, wenn sie ein zweites Mal ausgeführt wird.
Implementieren eines Begrüßungsbildschirms
In Fällen, in denen es eine erhebliche, unvermeidbare Verzögerung zwischen dem Starten einer Anwendung und der Anzeige der ersten Benutzeroberfläche gibt, optimieren Sie die wahrgenommene Startzeit mithilfe eines Begrüßungsbildschirms. Dieser Ansatz zeigt ein Bild fast unmittelbar nach dem Starten der Anwendung an. Wenn die Anwendung bereit ist, die erste Benutzeroberfläche anzuzeigen, wird der Begrüßungsbildschirm ausgeblendet. Ab .NET Framework 3.5 SP1 können Sie die SplashScreen Klasse verwenden, um einen Begrüßungsbildschirm zu implementieren. Weitere Informationen finden Sie unter Hinzufügen eines Begrüßungsbildschirms zu einer WPF-Anwendung.
Sie können auch ihren eigenen Begrüßungsbildschirm mithilfe nativer Win32-Grafiken implementieren. Zeigen Sie Ihre Implementierung an, bevor die Run Methode aufgerufen wird.
Analysieren des Startcodes
Ermitteln Sie den Grund für einen langsamen Kaltstart. Festplatten-I/O ist möglicherweise verantwortlich, aber dies ist nicht immer der Fall. Im Allgemeinen sollten Sie die Verwendung externer Ressourcen minimieren, z. B. Netzwerk, Webdienste oder Datenträger.
Stellen Sie vor dem Testen sicher, dass keine anderen ausgeführten Anwendungen oder Dienste verwalteten Code oder WPF-Code verwenden.
Starten Sie die WPF-Anwendung unmittelbar nach einem Neustart, und bestimmen Sie, wie lange die Anzeige dauert. Wenn alle nachfolgenden Starts Ihrer Anwendung (warmer Start) viel schneller sind, wird Ihr Kaltstartproblem höchstwahrscheinlich durch E/A verursacht.
Wenn das Problem beim Kaltstart ihrer Anwendung nicht mit E/A verbunden ist, ist es wahrscheinlich, dass Ihre Anwendung beim Start eine lange Initialisierung oder Berechnung durchführt, wartet auf den Abschluss eines Ereignisses oder erfordert eine Menge JIT-Kompilierung beim Start. In den folgenden Abschnitten werden einige dieser Situationen ausführlicher beschrieben.
Optimieren des Modulladevorgangs
Verwenden Sie Tools wie Prozess-Explorer (Procexp.exe) und Tlist.exe, um zu bestimmen, welche Module ihre Anwendung lädt. Der Befehl Tlist <pid>
zeigt alle Module an, die von einem Prozess geladen werden.
Wenn Sie beispielsweise keine Verbindung mit dem Web herstellen und sehen, dass System.Web.dll geladen wird, gibt es ein Modul in Ihrer Anwendung, das auf diese Assembly verweist. Überprüfen Sie, ob der Verweis tatsächlich erforderlich ist.
Wenn Ihre Anwendung über mehrere Module verfügt, führen Sie sie in einem einzigen Modul zusammen. Dieser Ansatz erfordert weniger CLR-Assemblyladeaufwand. Weniger Assemblys bedeuten auch, dass die CLR weniger Zustand behält.
Initialisierungsvorgänge zurückstellen
Erwägen Sie das Verschieben des Initialisierungscodes, bis das Hauptanwendungsfenster gerendert wurde.
Beachten Sie, dass die Initialisierung innerhalb eines Klassenkonstruktors ausgeführt werden kann und wenn der Initialisierungscode auf andere Klassen verweist, kann dies zu einem Kaskadierenden Effekt führen, in dem viele Klassenkonstruktoren ausgeführt werden.
Anwendungskonfiguration vermeiden
Erwägen Sie, die Anwendungskonfiguration zu vermeiden. Wenn eine Anwendung beispielsweise einfache Konfigurationsanforderungen hat und strenge Startzeitziele hat, können Registrierungseinträge oder eine einfache INI-Datei eine schnellere Startalternative sein.
Nutzen Sie das GAC
Wenn eine Assembly nicht im globalen Assemblycache (Global Assembly Cache, GAC) installiert ist, gibt es Verzögerungen, die durch die Hashüberprüfung von stark benannten Assemblys und durch die Ngen-Imageüberprüfung verursacht werden, wenn ein systemeigenes Image für diese Assembly auf dem Computer verfügbar ist. Die Überprüfung mit starkem Namen wird für alle Assemblys übersprungen, die im Global Assembly Cache (GAC) installiert sind. Weitere Informationen finden Sie unter Gacutil.exe (Global Assembly Cache-Tool).
Verwenden Sie Ngen.exe
Erwägen Sie die Verwendung des nativen Bildgenerators (Ngen.exe) für Ihre Anwendung. Die Verwendung von Ngen.exe bedeutet, dass der CPU-Verbrauch für mehr Datenträgerzugriff verwendet wird, da das systemeigene Image, das von Ngen.exe generiert wird, wahrscheinlich größer als das MSIL-Image ist.
Um die warme Startzeit zu verbessern, sollten Sie immer Ngen.exe für Ihre Anwendung verwenden, da dadurch die CPU-Kosten der JIT-Kompilierung des Anwendungscodes vermieden werden.
In einigen Kaltstartszenarien kann die Verwendung von Ngen.exe auch hilfreich sein. Dies liegt daran, dass der JIT-Compiler (mscorjit.dll) nicht geladen werden muss.
Sowohl Ngen- als auch JIT-Module können die schlimmsten Auswirkungen haben. Dies liegt daran, dass mscorjit.dll geladen werden muss, und wenn der JIT-Compiler Ihren Code bearbeitet, müssen viele Seiten in den Ngen-Bildern aufgerufen werden, wenn der JIT-Compiler die Metadaten der Assemblys liest.
Ngen und ClickOnce
Die Art und Weise, wie Sie Ihre Anwendung bereitstellen möchten, kann auch einen Unterschied bei der Ladezeit machen. Die ClickOnce-Anwendungsbereitstellung unterstützt Ngen nicht. Wenn Sie Ngen.exe für Ihre Anwendung verwenden möchten, müssen Sie einen anderen Bereitstellungsmechanismus wie Windows Installer verwenden.
Weitere Informationen finden Sie unter Ngen.exe (Native Image Generator).
Neubasieren und DLL-Adresskonflikte
Wenn Sie Ngen.exeverwenden, beachten Sie, dass eine Rebasierung auftreten kann, wenn die nativ kompilierten Bilder in den Arbeitsspeicher geladen werden. Wenn eine DLL nicht an der bevorzugten Basisadresse geladen wird, da dieser Adressbereich bereits zugeordnet ist, wird sie vom Windows-Ladeprogramm an eine andere Adresse geladen, was ein zeitaufwendiger Vorgang sein kann.
Mit dem Tool "Virtual Address Dump(Vadump.exe) können Sie überprüfen, ob Module vorhanden sind, in denen alle Seiten privat sind. Wenn dies der Fall ist, wurde das Modul möglicherweise auf eine andere Adresse zurückgestellt. Daher können seine Seiten nicht freigegeben werden.
Weitere Informationen zum Festlegen der Basisadresse finden Sie unterNgen.exe (Native Image Generator).For more information about how to set the base address, see Ngen.exe (Native Image Generator).
Optimieren von Authenticode
Die Authenticode-Überprüfung wird der Startzeit hinzugefügt. Authenticode-signierte Assemblies müssen mit der Zertifizierungsbehörde überprüft werden. Diese Überprüfung kann zeitaufwändig sein, da eine Mehrfachverbindung mit dem Netzwerk erforderlich sein kann, um aktuelle Zertifikatsperrlisten herunterzuladen. Es wird auch sichergestellt, dass auf dem Weg zu einem vertrauenswürdigen Stamm eine lückenlose Kette gültiger Zertifikate vorhanden ist. Dies kann zu mehreren Sekunden Verzögerung führen, während die Assembly geladen wird.
Erwägen Sie die Installation des Zertifizierungsstellenzertifikats auf dem Clientcomputer, oder vermeiden Sie die Verwendung von Authenticode, wenn dies möglich ist. Wenn Sie wissen, dass Ihre Anwendung den Herausgebernachweis nicht benötigt, müssen Sie die Kosten der Signaturüberprüfung nicht bezahlen.
Ab .NET Framework 3.5 gibt es eine Konfigurationsoption, mit der die Authenticode-Überprüfung umgangen werden kann. Fügen Sie hierzu der app.exe.config Datei die folgende Einstellung hinzu:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
Weitere Informationen finden Sie unter <generatePublisherEvidence> Element.
Vergleich der Leistung unter Windows Vista
Der Speicher-Manager in Windows Vista verfügt über eine Technologie namens SuperFetch. SuperFetch analysiert Speichernutzungsmuster im Laufe der Zeit, um den optimalen Speicherinhalt für einen bestimmten Benutzer zu ermitteln. Sie arbeitet kontinuierlich daran, diese Inhalte jederzeit aufrechtzuerhalten.
Dieser Ansatz unterscheidet sich von der in Windows XP verwendeten Vorababruftechnik, die Daten ohne Analyse von Verwendungsmustern in den Arbeitsspeicher vorab hochlädt. Wenn der Benutzer Ihre WPF-Anwendung im Laufe der Zeit häufig unter Windows Vista verwendet, kann sich die Kaltstartzeit Ihrer Anwendung verbessern.
Effizientes Verwenden von AppDomains
Laden Sie Assemblys nach Möglichkeit in einen domänenneutralen Codebereich, um sicherzustellen, dass das systemeigene Image, sofern vorhanden, in allen in der Anwendung erstellten AppDomains verwendet wird.
Um eine optimale Leistung zu erzielen, erzwingen Sie eine effiziente domänenübergreifende Kommunikation, indem Sie domänenübergreifende Anrufe reduzieren. Verwenden Sie nach Möglichkeit Aufrufe ohne Argumente oder mit primitiven Typargumenten.
Verwenden des NeutralResourcesLanguage-Attributs
Verwenden Sie die NeutralResourcesLanguageAttribute Zum Angeben der neutralen Kultur für die ResourceManager. Dieser Ansatz vermeidet erfolglose Assemblysuchvorgänge.
Verwenden des XML-Serialisierungsgenerators
Wenn Sie die XmlSerializer Klasse verwenden, können Sie eine bessere Leistung erzielen, wenn Sie die Serialisierungsassembly mithilfe des XML Serializer Generator-Tools (Sgen.exe) vorab generieren.
Konfigurieren von ClickOnce, um nach Updates nach dem Start zu suchen
Wenn Ihre Anwendung ClickOnce verwendet, vermeiden Sie den Netzwerkzugriff beim Start, indem Sie ClickOnce konfigurieren, um die Bereitstellungswebsite auf Updates zu überprüfen, nachdem die Anwendung gestartet wurde.
Wenn Sie das XAML-Browseranwendungsmodell (XBAP) verwenden, beachten Sie, dass ClickOnce die Bereitstellungswebsite auf Updates überprüft, auch wenn sich der XBAP bereits im ClickOnce-Cache befindet. Weitere Informationen finden Sie unter ClickOnce Security and Deployment.
Warnung
XBAPs erfordern, dass ältere Browser funktionieren, z. B. Internet Explorer und alte Versionen von Firefox. Diese älteren Browser werden in der Regel unter Windows 10 und Windows 11 nicht unterstützt. Moderne Browser unterstützen die für XBAP-Apps erforderliche Technologie aufgrund von Sicherheitsrisiken nicht mehr. Plug-Ins, die XBAPs aktivieren, werden nicht mehr unterstützt. Weitere Informationen finden Sie unter Häufig gestellte Fragen zu WPF-Anwendungen, die im Browser gehostet werden (XBAP).
Konfigurieren des PresentationFontCache-Diensts für den automatischen Start
Die erste WPF-Anwendung, die nach einem Neustart ausgeführt werden soll, ist der PresentationFontCache-Dienst. Der Dienst speichert die Systemschriftarten zwischen, optimiert den Zugriff auf Schriftarten und verbessert die Gesamtleistung. Es besteht ein Aufwand beim Starten des Diensts, und in einigen kontrollierten Umgebungen sollten Sie den Dienst so konfigurieren, dass er automatisch gestartet wird, wenn das System neu gestartet wird.
Programmgesteuertes Festlegen der Datenbindung
Anstatt XAML zum deklarativen Festlegen des DataContext Hauptfensters zu verwenden, sollten Sie es programmgesteuert in der OnActivated Methode festlegen.
Siehe auch
.NET Desktop feedback