Tempo di avvio delle applicazioniApplication Startup Time

La quantità di tempo necessaria per avviare un'applicazione WPF può variare notevolmente.The amount of time that is required for a WPF application to start can vary greatly. In questo argomento vengono descritte varie tecniche per ridurre il tempo di avvio percepito ed effettivo per un'applicazione Windows Presentation Foundation (WPF).This topic describes various techniques for reducing the perceived and actual startup time for a Windows Presentation Foundation (WPF) application.

Informazioni su avvio a freddo e avvio a caldoUnderstanding Cold Startup and Warm Startup

L'avvio a freddo si verifica quando un'applicazione viene avviata per la prima volta dopo un riavvio del sistema, o quando si avvia l'applicazione, la si chiude e quindi la si riavvia dopo un lungo periodo di tempo.Cold startup occurs when your application starts for the first time after a system reboot, or when you start your application, close it, and then start it again after a long period of time. All'avvio dell'applicazione, se le pagine necessarie (codice, dati statici, registro e così via) non sono presenti nell'elenco di standby del gestore della memoria di Windows, si verificano errori di pagina.When an application starts, if the required pages (code, static data, registry, etc) are not present in the Windows memory manager's standby list, page faults occur. L'accesso al disco è necessario per inserire le pagine in memoria.Disk access is required to bring the pages into memory.

L'avvio a caldo si verifica quando la maggior parte delle pagine per i componenti principali di Common Language Runtime (CLR) sono già caricata in memoria, il che consente di risparmiare molto tempo per l'accesso al disco.Warm startup occurs when most of the pages for the main common language runtime (CLR) components are already loaded in memory, which saves expensive disk access time. Ecco perché un'applicazione gestita si avvia più rapidamente quando viene eseguita per la seconda volta.That is why a managed application starts faster when it runs a second time.

Implementare la schermata inizialeImplement a Splash Screen

Nei casi in cui c'è un ritardo significativo e inevitabili tra l'avvio di un'applicazione e la visualizzazione della prima interfaccia utente, è possibile ottimizzare il tempo di avvio percepito usando una schermata iniziale.In cases where there is a significant, unavoidable delay between starting an application and displaying the first UI, optimize the perceived startup time by using a splash screen. Questo approccio consente di visualizzare un'immagine quasi immediatamente dopo l'avvio dell'applicazione da parte dell'utente.This approach displays an image almost immediately after the user starts the application. Quando l'applicazione è pronta per la visualizzazione della prima interfaccia utente, la schermata iniziale si dissolve.When the application is ready to display its first UI, the splash screen fades. A partire da .NET Framework 3.5 SP1, è possibile usare il SplashScreen classe per implementare la schermata iniziale.Starting in the .NET Framework 3.5 SP1, you can use the SplashScreen class to implement a splash screen. Vedere Aggiungere una schermata iniziale in un'applicazione WPF.For more information, see Add a Splash Screen to a WPF Application.

È anche possibile implementare la schermata iniziale con grafica Win32 nativa.You can also implement your own splash screen by using native Win32 graphics. Visualizzare l'implementazione prima di Run viene chiamato il metodo.Display your implementation before the Run method is called.

Analizzare il codice di avvioAnalyze the Startup Code

Determinare il motivo di un avvio a freddo lento.Determine the reason for a slow cold startup. La causa potrebbe essere il disco I/O, ma non sempre.Disk I/O may be responsible, but this is not always the case. In generale, è necessario ridurre l'uso di risorse esterne, ad esempio rete, servizi Web o disco.In general, you should minimize the use of external resources, such as network, Web services, or disk.

Prima di eseguire il test, verificare che nessun altra applicazione o servizio in esecuzione usi il codice gestito o WPF.Before you test, verify that no other running applications or services use managed code or WPF code.

Avviare l'applicazione WPF immediatamente dopo un riavvio e determinare il tempo richiesto per la visualizzazione.Start your WPF application immediately after a reboot, and determine how long it takes to display. Se tutti gli avvii successivi dell'applicazione (avvio a caldo) sono molto più veloci, il problema di avvio a freddo probabilmente è causato da I/O.If all subsequent launches of your application (warm startup) are much faster, your cold startup issue is most likely caused by I/O.

Se il problema di avvio a freddo dell'applicazione non è correlato all'I/O, è probabile che l'applicazione esegua una lunga inizializzazione o un calcolo, attenda il completamento di un evento o richieda una notevole quantità di compilazione JIT all'avvio.If your application's cold startup issue is not related to I/O, it is likely that your application performs some lengthy initialization or computation, waits for some event to complete, or requires a lot of JIT compilation at startup. Le sezioni seguenti descrivono alcune di queste situazioni in maggior dettaglio.The following sections describe some of these situations in more detail.

Ottimizzare il modulo di caricamentoOptimize Module Loading

Usare strumenti come Esplora processi (Procexp.exe) e Tlist.exe per determinare quali moduli l'applicazione carica.Use tools such as Process Explorer (Procexp.exe) and Tlist.exe to determine which modules your application loads. Il comando Tlist <pid> mostra tutti i moduli caricati da un processo.The command Tlist <pid> shows all the modules that are loaded by a process.

Ad esempio, se non ci si sta connettendo al Web e si nota che System.Web.dll è stato caricato, vi è un modulo nell'applicazione che fa riferimento a questo assembly.For example, if you are not connecting to the Web and you see that System.Web.dll is loaded, then there is a module in your application that references this assembly. Verificare che il riferimento sia necessario.Check to make sure that the reference is necessary.

Se l'applicazione dispone di più moduli, unirli in un unico modulo.If your application has multiple modules, merge them into a single module. Questo approccio richiede un minor sovraccarico di caricamento di assembly del CLR.This approach requires less CLR assembly-loading overhead. Un minor numero di assembly significa inoltre che CLR gestisce un minor numero di stati.Fewer assemblies also mean that the CLR maintains less state.

Rinviare le operazioni di inizializzazioneDefer Initialization Operations

È consigliabile posticipare il codice di inizializzazione dopo aver eseguito il rendering della finestra principale dell'applicazione.Consider postponing initialization code until after the main application window is rendered.

Tenere presente che l'inizializzazione può essere eseguita all'interno di un costruttore di classe, e se il codice di inizializzazione fa riferimento ad altre classi, può causare un effetto a catena in cui vengono eseguiti molti costruttori di classi.Be aware that initialization may be performed inside a class constructor, and if the initialization code references other classes, it can cause a cascading effect in which many class constructors are executed.

Evitare la configurazione dell'applicazioneAvoid Application Configuration

È consigliabile evitare la configurazione dell'applicazione.Consider avoiding application configuration. Ad esempio, se un'applicazione ha requisiti di configurazione semplici e tempi di avvio stretti, le voci del registro o di un semplice file INI potrebbero essere un'alternativa di avvio più veloce.For example, if an application has simple configuration requirements and has strict startup time goals, registry entries or a simple INI file may be a faster startup alternative.

Usare il GACUtilize the GAC

Se un assembly non è installato nella Global Assembly Cache (GAC), ci sono ritardi causati dalla verifica hash di assembly con nome sicuro e convalida dell'immagine Ngen se un'immagine nativa per tale assembly è disponibile nel computer.If an assembly is not installed in the Global Assembly Cache (GAC), there are delays caused by hash verification of strong-named assemblies and by Ngen image validation if a native image for that assembly is available on the computer. La verifica del nome sicuro viene ignorata per tutti gli assembly installati nella GAC.Strong-name verification is skipped for all assemblies installed in the GAC. Per altre informazioni, vedere Gacutil.exe (Global Assembly Cache Tool) (Strumento Global Assembly Cache, Gacutil.exe).For more information, see Gacutil.exe (Global Assembly Cache Tool).

Usare Ngen.exeUse Ngen.exe

È consigliabile usare il generatore di immagini native (Ngen.exe) nell'applicazione.Consider using the Native Image Generator (Ngen.exe) on your application. L'uso di Ngen.exe indica la negoziazione del consumo di CPU per un maggiore accesso al disco perché l'immagine nativa generata da Ngen.exe è probabilmente più grande dell'immagine MSIL.Using Ngen.exe means trading CPU consumption for more disk access because the native image generated by Ngen.exe is likely to be larger than the MSIL image.

Per migliorare il tempo di avvio a caldo, si deve usare sempre Ngen.exe sull'applicazione, poiché ciò consente di evitare il costo della CPU per la compilazione JIT del codice dell'applicazione.To improve the warm startup time, you should always use Ngen.exe on your application, because this avoids the CPU cost of JIT compilation of the application code.

In alcuni scenari di avvio a freddo, l'uso si Ngen.exe può essere utile,In some cold startup scenarios, using Ngen.exe can also be helpful. perché il compilatore JIT (mscorjit.dll) non deve essere caricato.This is because the JIT compiler (mscorjit.dll) does not have to be loaded.

La presenza di entrambi i moduli Ngen e JIT può avere effetti negativi,Having both Ngen and JIT modules can have the worst effect. perché è necessario caricare mscorjit.dll e quando il compilatore JIT opera sul codice, l'accesso a molte pagine nelle immagini Ngen deve avvenire quando il compilatore JIT legge i metadati degli assembly.This is because mscorjit.dll must be loaded, and when the JIT compiler works on your code, many pages in the Ngen images must be accessed when the JIT compiler reads the assemblies' metadata.

ClickOnce e NgenNgen and ClickOnce

Anche il modo in cui si prevede di distribuire l'applicazione può fare la differenza in fase di caricamento.The way you plan to deploy your application can also make a difference in load time. Distribuzione di applicazioni ClickOnce non supporta Ngen.ClickOnce application deployment does not support Ngen. Se si decide di usare Ngen.exe per l'applicazione, è necessario usare un altro meccanismo di distribuzione, ad esempio Windows Installer.If you decide to use Ngen.exe for your application, you will have to use another deployment mechanism, such as Windows Installer.

Per altre informazioni, vedere Ngen.exe (Native Image Generator).For more information, see Ngen.exe (Native Image Generator).

Riassegnazione e conflitti di indirizzi di DLLRebasing and DLL Address Collisions

Se si usa Ngen.exe, tenere presente che la riassegnazione può verificarsi quando le immagini native vengono caricate in memoria.If you use Ngen.exe, be aware that rebasing can occur when the native images are loaded in memory. Se una DLL non viene caricata all'indirizzo di base preferito perché tale intervallo di indirizzi è già stato allocato, il caricatore di Windows lo caricherà in un altro indirizzo. Questa può essere un'operazione impegnativa.If a DLL is not loaded at its preferred base address because that address range is already allocated, the Windows loader will load it at another address, which can be a time-consuming operation.

È possibile usare lo strumento Virtual Address Dump (Vadump.exe) per verificare se sono presenti moduli in cui tutte le pagine sono private.You can use the Virtual Address Dump (Vadump.exe) tool to check if there are modules in which all the pages are private. In questo caso, il modulo potrebbe stato riassegnato a un indirizzo diverso.If this is the case, the module may have been rebased to a different address. Di conseguenza, le pagine non possono essere condivise.Therefore, its pages cannot be shared.

Per altre informazioni su come impostare l'indirizzo di base, vedere Ngen.exe (Native Image Generator).For more information about how to set the base address, see Ngen.exe (Native Image Generator).

Ottimizzare AuthenticodeOptimize Authenticode

La verifica di Authenticode si aggiunge al tempo di avvio.Authenticode verification adds to the startup time. Gli assembly con firma Authenticode devono essere verificati con l'autorità di certificazione (CA).Authenticode-signed assemblies have to be verified with the certification authority (CA). Questa verifica può richiedere tempi lunghi, in quanto può essere necessario connettersi alla rete più volte per scaricare gli elenchi di revoca dei certificati attuali.This verification can be time consuming, because it can require connecting to the network several times to download current certificate revocation lists. Consente inoltre la presenza di una catena completa di certificati validi nel percorso a una fonte attendibile.It also makes sure that there is a full chain of valid certificates on the path to a trusted root. Questo può causare molti secondi di ritardo, mentre l'assembly viene caricato.This can translate to several seconds of delay while the assembly is being loaded.

Si consiglia di installare il certificato CA nel computer client oppure di evitare di usare Authenticode quando è possibile.Consider installing the CA certificate on the client computer, or avoid using Authenticode when it is possible. Se per l'applicazione non è richiesta la prova del server di pubblicazione, non è necessario pagare il costo della verifica della firma.If you know that your application does not need the publisher evidence, you do not have to pay the cost of signature verification.

A partire da .NET Framework 3.5, è presente un'opzione di configurazione che consente di ignorare la verifica Authenticode.Starting in .NET Framework 3.5, there is a configuration option that allows the Authenticode verification to be bypassed. A tale scopo, aggiungere la seguente impostazione nel file app.exe.config:To do this, add the following setting to the app.exe.config file:

<configuration>  
    <runtime>  
        <generatePublisherEvidence enabled="false"/>   
    </runtime>  
</configuration>  

Per ulteriori informazioni, vedere Elemento <generatePublisherEvidence>.For more information, see <generatePublisherEvidence> Element.

Confrontare le prestazioni in Windows VistaCompare Performance on Windows Vista

Il gestore della memoria in Windows Vista è una tecnologia denominata SuperFetch.The memory manager in Windows Vista has a technology called SuperFetch. SuperFetch analizza i modelli di uso della memoria nel tempo per determinare il contenuto della memoria ottimale per un utente specifico.SuperFetch analyzes memory usage patterns over time to determine the optimal memory content for a specific user. Funziona in modo continuo per garantire la disponibilità del contenuto in qualsiasi momento.It works continuously to maintain that content at all times.

Questo approccio è diverso dalla tecnica di recupero preliminare usata in Windows XP, che consente di precaricare i dati in memoria senza analisi dei modelli di uso.This approach differs from the pre-fetch technique used in Windows XP, which preloads data into memory without analyzing usage patterns. Nel corso del tempo, se l'utente usa spesso l'applicazione WPF in Windows Vista, il tempo di avvio a freddo dell'applicazione può migliorare.Over time, if the user uses your WPF application frequently on Windows Vista, the cold startup time of your application may improve.

Usare in modo efficiente AppDomainUse AppDomains Efficiently

Se possibile, caricare gli assembly in un'area di codice indipendente dal dominio per assicurarsi che l'immagine nativa, se presente, venga usata in tutti gli AppDomain creati nell'applicazione.If possible, load assemblies into a domain-neutral code area to make sure that the native image, if one exists, is used in all AppDomains created in the application.

Per prestazioni ottimali, applicare una comunicazione efficiente tra domini, riducendo le chiamate tra domini.For the best performance, enforce efficient cross-domain communication by reducing cross-domain calls. Quando possibile, usare le chiamate senza argomenti oppure con argomenti di tipo primitivo.When possible, use calls without arguments or with primitive type arguments.

Usare l'attributo NeutralResourcesLanguageUse the NeutralResourcesLanguage Attribute

Usare la NeutralResourcesLanguageAttribute per specificare le impostazioni cultura neutrali per il ResourceManager.Use the NeutralResourcesLanguageAttribute to specify the neutral culture for the ResourceManager. Questo approccio impedisce ricerche di assembly non riuscite.This approach avoids unsuccessful assembly lookups.

Usare la classe BinaryFormatter per la serializzazioneUse the BinaryFormatter Class for Serialization

Se è necessario utilizzare la serializzazione, usare il BinaryFormatter classe anziché il XmlSerializer classe.If you must use serialization, use the BinaryFormatter class instead of the XmlSerializer class. Il BinaryFormatter classe è implementata nella libreria di classe di Base (BCL) nell'assembly mscorlib. dll.The BinaryFormatter class is implemented in the Base Class Library (BCL) in the mscorlib.dll assembly. Il XmlSerializer viene implementata nell'assembly XML. dll, che potrebbe essere una DLL aggiuntiva da caricare.The XmlSerializer is implemented in the System.Xml.dll assembly, which might be an additional DLL to load.

Se è necessario usare il XmlSerializer (classe), è possibile ottenere prestazioni migliori se si genera prima l'assembly di serializzazione.If you must use the XmlSerializer class, you can achieve better performance if you pre-generate the serialization assembly.

Configurare ClickOnce per verificare gli aggiornamenti in seguito all'avvioConfigure ClickOnce to Check for Updates After Startup

Se l'applicazione utilizza ClickOnce, evitare l'accesso alla rete all'avvio configurando ClickOnce per verificare il sito di distribuzione degli aggiornamenti dopo l'avvio dell'applicazione.If your application uses ClickOnce, avoid network access on startup by configuring ClickOnce to check the deployment site for updates after the application starts.

Se si usa il modello XAML browser application (XBAP), tenere presente che ClickOnce controlla il sito di distribuzione degli aggiornamenti anche se l'applicazione XBAP è già nella cache di ClickOnce.If you use the XAML browser application (XBAP) model, keep in mind that ClickOnce checks the deployment site for updates even if the XBAP is already in the ClickOnce cache. Per altre informazioni, vedere ClickOnce Security and Deployment.For more information, see ClickOnce Security and Deployment.

Configurare l'avvio automatico del servizio PresentationFontCacheConfigure the PresentationFontCache Service to Start Automatically

La prima applicazione WPF da eseguire dopo un riavvio è il servizio PresentationFontCache.The first WPF application to run after a reboot is the PresentationFontCache service. Il servizio memorizza nella cache i tipi di carattere del sistema, migliora l'accesso al tipo di carattere e le prestazioni complessive.The service caches the system fonts, improves font access, and improves overall performance. Si verifica un sovraccarico all'avvio del servizio e in alcuni ambienti controllati, si consiglia di configurare l'avvio automatico del servizio al riavvio del sistema.There is an overhead in starting the service, and in some controlled environments, consider configuring the service to start automatically when the system reboots.

Impostare il data binding a livello di codiceSet Data Binding Programmatically

Anziché usare XAML per impostare il DataContext in modo dichiarativo per la finestra principale, è consigliabile impostarlo a livello di codice nel OnActivated (metodo).Instead of using XAML to set the DataContext declaratively for the main window, consider setting it programmatically in the OnActivated method.

Vedere ancheSee also