versione italiana versione italiana
english version english version

ASP.NET Process Model (Parte 2/3)

Processo ASP.NET ASP.NET non è un’estensione ISAPI, ma un processo esterno, cioè un eseguibile che gira out-of-process rispetto al processo chiamante.
L’eseguibile in questione si chiama ASPNET_WP.exe, dove WP sta per Worker Process. Nella versione Premium di ASP.NET l’eseguibile prende invece il nome di ASPNET_EWP, dove la “E” sta per Enterprise o Extended a seconda della manualistica. Per informazione, la versione Enterprise si differenzia dalla versione tradizionale per alcune caratteristiche avanzate fra cui l’utilizzo delle Sessioni esterne (in un servizio Windows esterno o in SQL Server) e opzioni di caching avanzate.
N.B. Nella versione definitiva, al momento non esistono più due versioni distinte di ASP.NET.
Quindi la versione standard comprende anche le caratteristiche della versione Enterprise.

Vediamo quindi come IIS redirige le richieste verso il processo esterno.

Visto che Internet Information Server non viene modificato (e non avrebbe senso) dall’installazione del Framework .NET l’interazione è sempre garantita da un’estensione ISAPI installata con ASP.NET.
L’estensione ASPNET_ISAPI.DLL viene chiamata in causa da IIS (tramite la medesima configurazione di qualunque altra estensione) per le richieste di file ASPX, ASMX/SOAP e DISCO (per la gestione dei Web Service), ASHX (ne parliamo fra poco) e per qualunque altra estensione abbia a che fare con ASP.NET.


 

E’ proprio l’estensione ASPNET_ISAPI a redirigere tutte le richieste verso il worker process di ASP.NET:

 

ASP.NET Worker Process

All’interno del worker process ogni estensione viene gestita con un HttpHandler, mentre ogni richiesta/risposta deve attraversare una serie configurabile di HttpModule.

Quest’architettura ci ricorda molta quella di IIS facendo due analogie; la prima fra HttpHandler e estensione ISAPI, l’altra fra HttpModule e filtri ISAPI.
Il meccanismo è infatti identico: ad ogni estensione gestita da ASP.NET viene associato un HttpHandler che si incaricherà di creare l’ambiente adatto alla scrittura del codice per ogni tipologia di file.
Esiste infatti un handler per le pagine ASP.NET (estensione ASPX), un altro per la gestione delle risposte dei web service (estensione ASMX o SOAP) e così via.

Prima che la richiesta raggiunga l’handler deve però attraversare tutti i moduli (HttpModule) configurati: ogni moduli può analizzare e/o modificare qualunque byte della richiesta; al termine dei lavori dell’handler la risposta attraversa in ordine inverso tutti i moduli configurati, i quali, ancora una volta, potranno eseguire operazioni sui byte della risposta.



 



Quest’elenco di passi da effettuare all’interno del worker process viene chiamato “Pipeline di esecuzione”.
Il primo step della pipeline è la creazione di un’istanza della classe HttpRuntime da cui viene creato l’oggetto HttpContext che rappresenta il contesto di esecuzione della richiesta/risposta. Da questo oggetto si possono ottenere i puntatori ai vari oggetti della richiesta e della risposta come Request, Response, Server ecc.
Il worker process processa tutte le richieste tramite la pipeline di escuzione per ogni thread di esecuzione (worker thread).
Alla prima richiesta di una estensione gestita da ASP.NET l’estensione ISAPI fa partire il processo ASPNET_WP come si può facilmente verificare con il Task Manager di Windows.
Il processo InetInfo e ASPNET_WP sono quindi ospitati in aree di memoria separati.
Di conseguenza, un crash processo ASP non danneggia il processo INetInfo; non solo, è possibile far ripartire le varie applicazioni ASP senza dover fermare il servizio web.
Se il processo esterno crasha per qualunque motivo, o viene “ucciso” manualmente, alla successiva richiesta per un’estensione gestita da ASP.NET l’estensione ISAPI fa ripartire il processo stesso.
Per testare questo meccanismo potremmo giocare sporco richiamando da una pagina di test una delle più amate/odiate API di Windows: Kernel32.dll. Una delle novità in ASP.NET è infatti quella di poter chiamare API “pure”, anche se ovviamente non dovrebbe essere quasi mai necessario visto che molte di esse sono rimappate su classi del Framework .NET.

Il codice C# necessario consta di qualche semplice riga:

 

<%@ Import namespace="System.Runtime.InteropServices" %>

 

<script runat="server">

[DllImport("KERNEL32.DLL")]

 

public extern static int ExitProcess(int code);

 

void Page_Load(Object sender, EventArgs e) {

    ExitProcess(13);

}

La configurazione del processo di ASP.NET si effettua tramite il file Machine.Config che risiede nella directory X:\WINNT\Microsoft.NET\Framework\versione\CONFIG.