Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le app .NET Multi-platform App UI (.NET MAUI) possono usare runtime e strategie di compilazione diverse a seconda della piattaforma di destinazione, della configurazione di compilazione e del modello di distribuzione. Questo articolo illustra i termini chiave e le strategie di runtime e compilazione che .NET MAUI usano in ogni piattaforma.
Runtime
Un runtime .NET è l'ambiente di esecuzione che gestisce la memoria, il sistema dei tipi, la raccolta dei rifiuti e l'esecuzione del codice dell'applicazione. .NET MAUI app usano uno dei runtime seguenti:
Mono
Mono è il runtime multipiattaforma .NET che ha storicamente alimentato app Xamarin e app .NET MAUI in Android, iOS e Mac Catalyst. Mono supporta sia la compilazione JIT (Just-In-Time) che la compilazione AOT (Ahead-of-Time). Mono è il runtime predefinito per le app MAUI .NET nelle piattaforme Mobili e Mac Catalyst.
Mono non è supportato per le app .NET MAUI destinate .NET 11+.
Coreclr
CoreCLR è .NET Common Language Runtime usato da .NET nelle piattaforme desktop e server. Alimenta ASP.NET Core, le applicazioni console e le applicazioni desktop per Windows. CoreCLR offre un compilatore JIT altamente ottimizzato, una compilazione a livelli e un set completo di diagnostica di runtime.
In .NET MAUI CoreCLR è il runtime usato in Windows. In .NET 10 CoreCLR è disponibile anche come opzione sperimentale per Android.
In .NET 11+, CoreCLR è il runtime predefinito per le app .NET MAUI in Windows, Android, iOS e Mac Catalyst. NativeAOT è un'alternativa facoltativa per la pubblicazione in tutte le piattaforme di destinazione di .NET 11. Il supporto nativeAOT è sperimentale in Android.
NativeAOT
Quando si pubblica con AOT nativo, l'app non viene eseguita nel runtime CoreCLR. Viene invece eseguito in un runtime NativeAOT minimo collegato in modo statico al file binario nativo. Questo runtime include un Garbage Collector e un sistema di tipi, ma nessun compilatore o interprete JIT. Tutto il codice viene compilato in codice del computer nativo in fase di compilazione.
Strategie di compilazione
Una strategia di compilazione determina il modo in cui il codice C# viene trasformato in codice computer che il processore può eseguire. .NET MAUI usa diverse strategie di compilazione, a seconda dello scenario di runtime e distribuzione.
Compilazione JIT (JUST-in-Time)
La compilazione JIT converte Microsoft Intermediate Language (MSIL) in codice del computer nativo in fase di esecuzione quando vengono chiamati i metodi per la prima volta. La compilazione JIT consente rapidi cicli di compilazione-distribuzione-debug e funzionalità come Modifica e continuazione.
- Usato da: CoreCLR in Windows e sperimentalmente in Android; Mono nelle compilazioni di debug Android
- Vantaggi: tempi di compilazione rapidi, diagnostica completa del runtime e supporto per la generazione di codice dinamico
- Svantaggi: avvio più lento perché il codice viene compilato nel dispositivo in fase di esecuzione
- Utilizzato da: CoreCLR su Windows e Android
- Vantaggi: tempi di compilazione rapidi, diagnostica completa del runtime e supporto per la generazione di codice dinamico
- Svantaggi: avvio più lento quando il codice non è già compilato da ReadyToRun
Le destinazioni dei dispositivi Apple CoreCLR non usano JIT perché le restrizioni della piattaforma Apple impediscono il codice generato dinamicamente. Usano invece l'interprete CoreCLR.
Compilazione Mono AOT (Ahead-of-Time - Compilazione Anticipata)
La compilazione Mono AOT precompila MSIL in codice nativo in fase di compilazione usando il compilatore AOT di Mono. Questa è la modalità di compilazione predefinita per le build della versione MAUI di .NET su iOS, Mac Catalyst e Android.
- Usato da: il runtime Mono su iOS, Mac Catalyst e Android
- Vantaggi: avvio più rapido rispetto a JIT e necessario per le piattaforme che limitano la generazione di codice dinamico
- Svantaggi: dimensioni dell'app più grandi rispetto alle build solo JIT e supporto limitato per alcune funzionalità dinamiche
Mono AOT non è uguale a NativeAOT. Con Mono AOT, l'app include ancora il runtime mono e può facoltativamente usare l'interprete Mono per il codice che non è stato compilato con AOT. NativeAOT compila tutto il codice in anticipo e non include un interprete o JIT. Mono supporta anche una modalità AOT completa in cui non è disponibile alcun interprete o JIT. L'AOT completo viene usato per impostazione predefinita per le build di versione Mono in iOS e Mac Catalyst.
Compilazione NativeAOT (Native Ahead-of-Time)
NativeAOT compila l'intera app, le relative dipendenze e un runtime minimo in un file binario nativo in fase di compilazione. Non esiste alcun compilatore JIT o interprete in fase di esecuzione. NativeAOT esegue il taglio completo e l'analisi statica, che può produrre dimensioni più piccole delle app e tempi di avvio più rapidi, ma pone più restrizioni sui modelli di codice che è possibile usare.
- Disponibile in: .NET MAUI app iOS e Mac Catalyst quando sono abilitate in modo esplicito per la pubblicazione
- Vantaggi: piccole dimensioni dell'app, avvio rapido e un singolo file binario nativo
- Svantaggi: tempi di compilazione più lunghi, nessuna generazione dinamica di codice né caricamento dinamico, e tutto il codice deve essere compatibile con il trimming e con AOT
-
Proprietà MSBuild:
<PublishAot>true</PublishAot>
- Disponibile in: tutte le piattaforme di destinazione .NET MAUI, se esplicitamente abilitate per la pubblicazione. Il supporto nativeAOT è sperimentale in Android.
- Vantaggi: piccole dimensioni dell'app, avvio rapido e un singolo file binario nativo
- Svantaggi: tempi di compilazione più lunghi, nessuna generazione dinamica di codice né caricamento dinamico, e tutto il codice deve essere compatibile con il trimming e con l'AOT
-
Proprietà MSBuild:
<PublishAot>true</PublishAot>
NativeAOT è un modello di distribuzione di sola pubblicazione. Usare dotnet publish per produrre e convalidare un'app NativeAOT. Una compilazione di debug normale non usa NativeAOT.
Per altre informazioni, vedere Distribuzione AOT nativa in iOS e Mac Catalyst e distribuzione AOT nativa.
ReadyToRun (R2R)
ReadyToRun è una forma di compilazione anticipata per CoreCLR che precompila gli assembly in un formato contenente sia il codice MSIL originale che una rappresentazione di codice nativo. All'avvio, il runtime può usare il codice nativo precompilato anziché compilare metodi da MSIL. Nelle piattaforme in cui è disponibile JIT, il runtime può comunque compilare metodi JIT che non sono precompilati e ottimizzano i metodi usati di frequente in fase di esecuzione.
- Usato da: CoreCLR in Windows e build CoreCLR Android che optano per il runtime sperimentale
- Vantaggi: tempo di avvio migliorato mantenendo la compatibilità JIT
- Svantaggi: dimensioni di assembly maggiori perché gli assembly contengono sia codice MSIL che codice nativo
-
Proprietà MSBuild:
<PublishReadyToRun>true</PublishReadyToRun>
ReadyToRun è abilitato per impostazione predefinita per le app .NET MAUI in Windows in Release modalità e per le app Android che usano CoreCLR (sperimentale) in Release modalità.
Le immagini R2R vengono compresse all'interno dei .dll file.
- Usato da: CoreCLR in Windows, Android, iOS e Mac Catalyst
- Vantaggi: tempo di avvio migliorato mantenendo il comportamento di compilazione di runtime appropriato
- Svantaggi: dimensioni maggiori dell'applicazione e dei download
Per le app Android, ReadyToRun è abilitato per impostazione predefinita nella Release configurazione. Il valore predefinito è ReadyToRun parziale composito. Full ReadyToRun può essere abilitato con MauiEnableFullReadyToRun=true. Può migliorare le prestazioni di avvio o di runtime, ma aumenta le dimensioni del pacchetto, in modo da misurare il risultato per l'app.
Per le app iOS e Mac Catalyst, nelle compilazioni Release viene usato ReadyToRun composito parziale e nelle compilazioni Debug viene usato ReadyToRun composito completo. L'interprete CoreCLR è sempre abilitato ed esegue codice non precompilato perché queste piattaforme non consentono la compilazione JIT.
Composito R2R compila gli assembly insieme, abilitando le ottimizzazioni tra assembly. Parziale R2R precompila i metodi selezionati lasciando i metodi rimanenti per la compilazione in fase di esecuzione, mentre r2R completa precompila tutti i metodi.
Per altre informazioni, vedere Compilazione ReadyToRun.
Ottimizzazione guidata dal profilo (PGO)
L'ottimizzazione PGO (Profile-Guided Optimization) usa i dati di profilatura per guidare il compilatore verso la produzione di codice più efficiente. Nel contesto di .NET MAUI, esistono due forme di PGO:
-
PGO statico con profili MIBC: .NET MAUI viene fornito con file di profilo
.mibccontenenti dati sui metodi chiamati frequentemente durante il tipico avvio e utilizzo dell'app. Quando la compilazione ReadyToRun è abilitata, il compilatore R2R usa questi profili per decidere quali metodi precompilare. - PGO dinamico: in CoreCLR, il compilatore JIT può raccogliere i dati del profilo in fase di esecuzione e usarli quando i metodi vengono ricompilati con altre ottimizzazioni.
Per altre informazioni, vedere Ottimizzazione guidata dal profilo e Compilazione ReadyToRun.
Interprete Mono
L'interprete Mono consente a un'app di interpretare MSIL in fase di esecuzione senza generare codice nativo in modo dinamico. Viene usato insieme a Mono AOT su piattaforme che non consentono la compilazione JIT, ad esempio i dispositivi iOS.
L'interprete Mono abilita anche il ricaricamento rapido .NET per le app in esecuzione nel runtime mono.
UseInterpreter è impostato su true per impostazione predefinita in modalità Debug su Android, iOS e Mac Catalyst.
- Usato da: runtime Mono
- Vantaggi: supporta funzionalità dinamiche che AOT non può gestire, abilita .NET Ricaricamento rapido e può ridurre le dimensioni delle app
- Svantaggi: il codice interpretato viene eseguito più lentamente del codice compilato
-
Proprietà MSBuild:
<UseInterpreter>true</UseInterpreter>
Per altre informazioni, vedere Interprete Mono in iOS e Mac Catalyst.
interprete CoreCLR
CoreCLR include un interprete su iOS e Mac Catalyst. L'interprete è sempre abilitato ed esegue codice non precompilato perché queste piattaforme non consentono la compilazione JIT. Questo comportamento fa parte del runtime e non richiede una proprietà MSBuild dell'interprete.
Che cosa usa .NET MAUI per impostazione predefinita
La tabella seguente riepiloga la strategia di runtime e compilazione usata da .NET MAUI in ogni piattaforma, in base alla configurazione di compilazione:
| Piattaforma | Debug | Rilascio |
|---|---|---|
| Android | Mono + JIT + Interpreter | Mono + Mono AOT |
| iOS | Mono + JIT (x64) / Mono + AOT + interprete (ARM64) | Mono + Mono AOT |
| Mac Catalyst | Mono + JIT (x64) / Mono + AOT + interprete (ARM64) | Mono + Mono AOT |
| Windows | CoreCLR + JIT | CoreCLR + JIT + ReadyToRun |
Annotazioni
Quando si acconsente esplicitamente a CoreCLR in Android o iOS impostando <UseMonoRuntime>false</UseMonoRuntime> nel file di progetto, le compilazioni usano ReadyToRun per impostazione predefinita. Su iOS e Mac Catalyst con CoreCLR, Composite ReadyToRun è abilitato sia per le build di debug sia per le build di rilascio.
Suggerimento
È possibile acconsentire esplicitamente a NativeAOT in iOS e Mac Catalyst impostando <PublishAot>true</PublishAot> nel file di progetto. NativeAOT ha effetto solo durante la pubblicazione.
La tabella seguente riepiloga la strategia di runtime e compilazione usata da .NET MAUI in ogni piattaforma:
| Piattaforma | Debug | Rilascio |
|---|---|---|
| Android | CoreCLR + JIT | CoreCLR + composite partial ReadyToRun + JIT |
| iOS | CoreCLR + ReadyToRun parziale composito + interprete | CoreCLR + ReadyToRun composito completo + interprete |
| Mac Catalyst | CoreCLR + composite partial ReadyToRun + interprete | CoreCLR + ReadyToRun completo composito + interprete |
| Windows | CoreCLR + JIT | CoreCLR + JIT + ReadyToRun |
Importante
Non impostare UseMonoRuntime su true quando la destinazione è .NET 11+. Mono non è supportato e l'impostazione di questa proprietà genera un errore di compilazione.
Suggerimento
NativeAOT è abilitato con <PublishAot>true</PublishAot> e diventa effettivo quando si usa dotnet publish. NativeAOT non dispone di un JIT né di un interprete e richiede un trimming completo.
Confronto
La tabella seguente confronta le strategie di compilazione disponibili per le app MAUI .NET:
| Strategia | JIT | Mono AOT | ReadyToRun | NativeAOT |
|---|---|---|---|---|
| Tempo di compilazione | In fase di esecuzione | In fase di compilazione | In fase di compilazione | In fase di compilazione |
| Velocità di avvio | Più lento | Veloce | Veloce | Il più veloce |
| Velocità di stato costante | Più veloce (JIT ottimizzato) | Bene | Più veloce (ricompilazione incrementale a livelli) | Bene |
| Dimensioni dell'app | Più piccolo | Maggiore | Maggiore | Più piccolo |
| Codice dinamico | Supporto completo | Limitato | Supporto completo | Non supportato |
| Taglio obbligatorio | No | Parziale (impostazione predefinita) | No | Completo |
| Diagnostica | Completo | Limitato | Completo | Limitato |
Prestazioni tipiche
I benchmark seguenti provengono da un'app dotnet new maui e dipendono dall'hardware. Illustrano le differenze relative tra i runtime e non sono garanzie assolute.
Tempo di avvio (millisecondi):
| Runtime | Android | iOS | macOS |
|---|---|---|---|
| Mono (impostazione predefinita) | ~642 | ~275 | ~311 |
| NativeAOT | ~274 | ~130 | ~255 |
Dimensioni dell'app in iOS (MB):
| Modello di distribuzione | Dimensione |
|---|---|
| Mono (impostazione predefinita) | ~14.3 |
| Mono (ritaglio completo) | ~11.5 |
| NativeAOT | ~5.4 |
La tabella seguente confronta le strategie di compilazione disponibili per le app .NET MAUI destinate a .NET 11:
| Strategia | CoreCLR JIT | interprete CoreCLR | ReadyToRun | NativeAOT |
|---|---|---|---|---|
| Tempo di compilazione | In fase di esecuzione | In fase di esecuzione | In fase di compilazione | In fase di compilazione |
| Velocità di avvio | Più lento | Più lento | Veloce | Il più veloce |
| Dimensioni dell'app | Più piccolo | Più piccolo | Maggiore | Più piccolo |
| Codice dinamico | Supporto completo | Supporto completo | Supporto completo (tramite JIT o interprete) | Non supportato |
| Diagnostica | Completo | Completo | Limitato | Limitato |
CoreCLR in Android e iOS
A partire da .NET 10, è possibile acconsentire esplicitamente all'esecuzione di un'app Android in CoreCLR invece di Mono.
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
<UseMonoRuntime>false</UseMonoRuntime>
</PropertyGroup>
In .NET 10 CoreCLR in Android è una funzionalità sperimentale e non è destinata all'uso in produzione.
In .NET 11+, CoreCLR è il runtime predefinito per le app Android, iOS e Mac Catalyst. NativeAOT è un'alternativa di consenso esplicito che non usa CoreCLR ed è sperimentale in Android. Non impostare UseMonoRuntime=true; Mono non è supportato per .NET 11+ e l'impostazione della proprietà genera un errore di compilazione.
All'interno di un APK Android
Il contenuto di un APK varia a seconda della strategia di runtime e compilazione usata dall'app:
Mono:
-
classes.dex— Codice Java/Kotlin -
lib/arm64-v8a/libmonosgen-2.0.so— Mono Runtime -
lib/arm64-v8a/libmonodroid.so— Codice di integrazione per l'avvio del runtime specifico di Android -
lib/arm64-v8a/libassemblies.arm64-v8a.blob.so— Assembly MSIL compressi e impacchettati -
lib/arm64-v8a/libaot-*.dll.so— Immagini native mono AOT nelle build di rilascio
CoreCLR:
-
classes.dex— Codice Java/Kotlin -
lib/arm64-v8a/libcoreclr.so— Runtime CoreCLR -
lib/arm64-v8a/libclrjit.so— Compilatore JIT CoreCLR -
lib/arm64-v8a/libmonodroid.so— codice di avvio del runtime specifico per Android -
lib/arm64-v8a/libassemblies.arm64-v8a.so— MSIL impacchettato con immagini ReadyToRun
Il contenuto di un APK Android varia a seconda che l'app usi CoreCLR o NativeAOT:
CoreCLR:
-
classes.dex— Codice Java/Kotlin -
lib/arm64-v8a/libcoreclr.so— Runtime CoreCLR -
lib/arm64-v8a/libclrjit.so— Compilatore JIT CoreCLR -
lib/arm64-v8a/libmonodroid.so— codice di integrazione per l'avvio dell'ambiente di runtime specifico di Android -
lib/arm64-v8a/libassembly-store.so— MSIL compresso con immagini ReadyToRun
NativeAOT in Android (sperimentale):
-
classes.dex— Codice Java/Kotlin -
lib/arm64-v8a/libhellomaui.so— Libreria nativa contenente il runtime, il codice gestito e il codice di avvio
Taglio
Trimming è un passaggio di compilazione che rimuove il codice inutilizzato dall'app per ridurne le dimensioni. .NET MAUI usa il trimmer ILLink, che analizza il codice e rimuove tipi, metodi e campi a cui non viene fatto riferimento staticamente.
Per le build di rilascio CoreCLR, .NET MAUI usa TrimMode=partial per impostazione predefinita, che riduce gli assembly del framework, ma non il codice dell’app né i riferimenti NuGet. Per usare il trimming completo, impostare TrimMode su full:
<PropertyGroup>
<TrimMode>full</TrimMode>
</PropertyGroup>
NativeAOT esegue automaticamente il taglio completo. Non impostare TrimMode per selezionare una modalità di taglio diversa quando si usa NativeAOT.
Per altre informazioni, vedere Ottimizzare un'app .NET MAUI.
Informazioni di riferimento sulle proprietà di MSBuild
La tabella seguente riepiloga le proprietà di MSBuild che controllano il comportamento di runtime e compilazione:
| Proprietà | Descrizione | Impostazione predefinita |
|---|---|---|
PublishAot |
Abilitare la compilazione NativeAOT. | false |
PublishReadyToRun |
Abilitare la precompilazione ReadyToRun per CoreCLR. |
true (release di Windows e build CoreCLR correlate) |
PublishTrimmed |
Abilitare la riduzione ILLink. |
true (Versione) |
TrimMode |
Impostare l'aggressività di taglio (partial o full). |
partial |
UseInterpreter |
Abilitare l'interprete Mono. |
true (Debugging Catalyst per iOS/Mac) |
UseMonoRuntime |
Usare Mono anziché CoreCLR. |
true nelle destinazioni Mono supportate |
La tabella seguente riepiloga le proprietà di MSBuild rilevanti per il comportamento di runtime e compilazione di .NET 11:
| Proprietà | Descrizione | Impostazione predefinita |
|---|---|---|
PublishAot |
Abilitare la compilazione NativeAOT durante dotnet publish. |
false |
MauiEnableFullReadyToRun |
Abilitare ReadyToRun completo per le app Android CoreCLR. | false |
TrimMode |
Impostare l'aggressività di taglio per le compilazioni non NativeAOT. | partial |