Dovrei preoccuparmi del caricamento lento in un'applicazione Web?
-
06-07-2019 - |
Domanda
Ho imparato che per avere un caricamento pigro singleton, questo è lo schema da usare:
private MyObject()
{
}
public static MyObject Instance
{
get { return SingletonCreator.CreatorInstance; }
}
private static class SingletonCreator
{
private static readonly MyObject _instance = new MyObject();
public static MyObject CreatorInstance
{
get { return _instance; }
}
}
Ma un modello più semplice sarebbe:
private static readonly MyObject _instance = new MyObject();
private MyObject()
{
}
public static MyObject Instance
{
get { return _instance; }
}
Questo non sarebbe un caricamento lento. Ma è davvero qualcosa di cui dovrei preoccuparmi in un'applicazione web?
Soluzione
A meno che tu non abbia metodi statici che non richiedono il singleton, è sufficiente includere un costruttore statico per rendere pigra la classe. Senza il costruttore statico è ancora per lo più pigro.
Vedi la mia pagina di implementazione singleton per maggiori dettagli e opzioni.
Normalmente avrei il codice che hai dato in fondo alla domanda - è abbastanza pigro, a meno che tu davvero non voglia inizializzare il singleton a meno che non venga usato. (Fondamentalmente con beforefieldinit
impostato, JIT generalmente si assicurerà che ogni tipo utilizzato in un metodo sia inizializzato; senza beforefieldinit
deve attendere fino al primo effettivo utilizzo della classe durante l'esecuzione. Vedi la mia beforefieldinit
per ulteriori informazioni - ma il punto importante è che non verrà ancora inizializzato tutti i singoli dopo il caricamento dell'assembly, o qualcosa del genere.)
Altri suggerimenti
Il caricamento lento di solito implica che stai caricando pigramente qualcosa da un database. Quello che stai facendo di solito è chiamato " inizializzazione pigra " (tecnicamente "l'inizializzazione lenta" è un metodo di implementazione di un modello di caricamento lento).
Per quanto riguarda le tue domande originali: prima di tutto, non hai bisogno di un singleton. Se ancora ne hai bisogno, ecco come dovrebbe essere fatto correttamente. Terzo, non hai bisogno di un singleton.
Va ??bene, ma il punto di caricamento lento è evitare il caricamento di risorse (di solito non gestite) (colpire un database, il filesystem, ecc.) fino a quando non è necessario, il che evita di caricarle preventivamente quando si è davvero necessario. L'uso del modello singleton, di per sé, non implica necessariamente il caricamento lento, poiché è possibile creare correttamente l'istanza gestita in qualsiasi momento.
L'aspetto di caricamento lento entra in gioco se si accede a qualsiasi risorsa caricata solo quando viene effettuata la chiamata del metodo appropriata; se, quando viene creata quell'istanza singleton, esegue un sacco di query sul database e blocca il risultato, quindi non è un caricamento lento per quanto mi riguarda.
Per quanto riguarda gli scenari ORM, il caricamento lento di solito si riferisce direttamente al differimento del carico di un altro oggetto in una relazione fino al primo accesso, il che evita di eseguire una seconda query potenzialmente superflua.
Quindi, se sai che navigherai quella relazione nel corso del tuo uso dell'oggetto (cioè se hai recuperato un User
per elencare il loro
Assicurarsi di non confondere il caricamento della pagina, la durata della sessione e dell'applicazione. Detto questo, sei sicuro di voler utilizzare un'istanza singleton statica? Una volta creato, rimarrà attivo fino a quando l'applicazione (il server web) non verrà chiusa o non eseguirai iisreset .
Prendi in considerazione la memorizzazione nella cache in HttpContext.Current.Items
invece se desideri un'istanza caricata pigramente per caricamento della pagina, o forse in HttpContext.Current.Session
se ne desideri una per utente.