Che cosa si potrebbe vedere che viene comunemente indicato come l'agilità filo in .NET.
Quello che si sta probabilmente vedendo fino ai risultati al di sotto dell'etichetta topica (ad esempio il codice dell'applicazione in System.Web.HttpApplication.BeginRequest()
) è un problema di agilità del thread; nella maggior parte dei casi il tempo che vedete qui non è necessariamente il codice che viene eseguito, ma il contesto web in attesa che i thread vengano rilasciati da un blocco di lettore-scrittore.
La "pausa" Application_BeginRequest()
è uno che è abbastanza pervasivo in uno stack Web ASP.NET. In generale, quando si visualizzano tempi di caricamento lunghi in BeginRequest, si ha a che fare con agilità di thread ASP.NET e/o blocchi di thread, specialmente quando si ha a che fare con operazioni IO e basate su sessioni. Non che sia una brutta cosa, questo è solo il modo .net assicura che i tuoi thread rimangano concomitanti.
Il divario di tempo si verifica in genere tra BeginRequest e PreRequestHandlerExecute. Se l'applicazione sta scrivendo diverse cose per la sessione, ASP.NET emetterà un blocco lettore-scrittore su HttpContext.Current.Session
.
Un buon modo per vedere se questo è un problema che si potrebbe affrontare sarebbe quello di controllare gli ID del thread per vedere se l'agilità è un problema - gli ID saranno diversi per una determinata richiesta.
Per esempio. Durante il debug, forse si potrebbe aggiungere quanto segue al Global.asax.cs
:
protected void Application_BeginRequest(Object sender, EventArgs e) {
Debug.WriteLine("BeginRequest_" + Thread.CurrentThread.ManagedThreadId.ToString());
}
aprire la finestra di output di debug (da Visual Studio: View >> uscita, quindi selezionare "Debug" dal "spettacolo di uscita dal" menu a discesa) .
Durante il debug, premere una pagina in cui si è visto il tempo lungo. Quindi visualizza il log di output: se vedi più ID, potresti soffrire di questo.
Questo è il motivo per cui a volte è possibile vedere il ritardo ma non altre volte, il codice dell'applicazione potrebbe utilizzare la sessione in modo leggermente diverso o le operazioni di I/O potrebbero essere più alte o più basse da una pagina all'altra.
Se questo è il caso, alcune cose che puoi fare per velocizzare le cose a seconda di come la sessione viene usata sul sito o su ciascuna pagina.
Per le pagine che non modificano sessione:
<% @Page EnableSessionState="ReadOnly" %>
Per le pagine che non utilizzano sessione di Stato:
<% @Page EnableSessionState="False" %>
Se l'applicazione non fa uso di sessione (web.config):
Quindi prendiamo il seguente esempio:
L'utente carica una pagina, quindi decide di passare a un'altra pagina prima che la prima richiesta venga completata caricando ASP.NET imporrà un blocco di sessione che causa il caricamento della nuova pagina di attesa per il completamento della richiesta della prima pagina. Con ASP.NET MVC ogni azione blocca la sessione utente per la sincronizzazione; causando lo stesso problema.
Tutto il tempo necessario per il rilascio del blocco verrà segnalato tramite nuova reliquia, per non parlare di quelli in cui l'utente ha abbandonato la sessione e il thread che sta tornando sta cercando un utente che non esiste più.
Tra l'altro il controllo UpdatePanel provoca lo stesso comportamento -
http://msdn.microsoft.com/en-us/magazine/cc163413.aspx
cosa si può fare:
Questo problema di blocco è uno dei motivi che Microsoft ha la classe SessionStateUtility -
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx
In modo da poter ignorare il comportamento predefinito r se si affronta questo problema come si vede qui in questa implementazione Redis : https://github.com/angieslist/AL-Redis
Ci sono molte opzioni per il provider di stato predefinito utilizzato dai siti Web basati su .net. Ma in genere questo tempo di transazione indica che i thread vengono bloccati e in attesa di completamento delle richieste al server.
http://blog.stevensanderson.com/blogfiles/2007/ASPNET-MVC-Pipeline/ASP.NET%20MVC%20Pipeline.pdf –
@Ravi BeginRequest() non è lì! :( –
Stai usando gestori asincroni (IHttpAsyncHandler)? –