Caching di pagine ASP.NET

venerdì 08 marzo 2013 - 11.36
Tag Elenco Tags  VB.NET  |  .NET 4.0  |  Visual Studio 2010

trinity Profilo | Guru

Salve ragazzi....prima di tutto vorrei porre questa domanda..il salvataggio dei dati in cache avviene sulla macchina dell'utente o sul server web dove risiedono le pagine web?

ciao
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Salve ragazzi....prima di tutto vorrei porre questa domanda..il
>salvataggio dei dati in cache avviene sulla macchina dell'utente
>o sul server web dove risiedono le pagine web?
ciao,
dalla documentazione (http://msdn.microsoft.com/it-it/library/xsbfdd8c(v=vs.100).aspx):
"One of the most important factors in building high-performance, scalable Web applications is the ability to store items, whether data objects, pages, or parts of a page, in memory the initial time they are requested. You can cache, or store, these items on the Web server or other software in the request stream, such as the proxy server or browser. This allows you to avoid recreating information that satisfied a previous request, particularly information that demands significant processor time or other resources. ASP.NET caching allows you to use a number of techniques to store page output or application data across HTTP requests and reuse it.
ASP.NET provides two types of caching that you can use to create high-performance Web applications. The first is output caching, which allows you to store dynamic page and user control responses on any HTTP 1.1 cache-capable device in the output stream, from the originating server to the requesting browser. On subsequent requests, the page or user control code is not executed; the cached output is used to satisfy the request. The second type of caching is application data caching, which you can use to programmatically store arbitrary objects, such as application data, in server memory so that your application can save the time and resources it takes to recreate them."
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://blogs.dotnethell.it/suxstellino
http://suxstellino.wordpress.com
http://mvp.microsoft.com/profiles/Alessandro.Alpi

trinity Profilo | Guru

Quindi viene salvata nella memria del server web..oppure ho capito e letto male...Ho posto questa domanda del caching perchè mi trovi di fronte ad una questione di prestazioni su un mio progetto...ossia ho creato due pagine aspx le quali servono ad effettuare delle ricerche di record in in database sql e la visualizzazione di tale ricerche...ecco dato che nella pagina destina alla visualizzazione ho messo una radlistview e un datapager per sfogliare le pagine qualcora vengano ricercarti molti record...prima di pensare all'utilizzo del caching, ogni volta che cliccavo sul datapage veniva ripetuto il codice sql (quindi connessione al db ed esecuzione della stored di ricecra) per poi passarlo al source della radlistview....allora cosa ho pesnato dato che ci possono essere simultaneamente anche molti utenti che utilizzano questa ricerca, per evitare di eseguire sempre chiamate al database, ho pensato di ricorrere la caching dei dati per far si che una volta ricercata la parola che mi serve e restituiti i record della ricerca questi vengono salvati nella cache così l'utente può sfogliare tranquillamente i dati e le pagine senza che venga ogni volta fatta una richiesta al db...ovviamente se i parametri di ricerca vengono cambiati allora si deve rifare la chiamata al database, per questo motivo utiliziando delle querystring, nella pagina ho scritto questo: <%@ OutputCache duration="10" VaryByParam="string1,string2" %>...

Ora il mio dubbio era sul fatto che se i dati vengono salvati sulla cache del pc locale dell'utente allora si chele prestazioni sono elevate anche se nel casi si connetto alla sito web per fare le ricerche moltissimi utenti, nel caso invece che la cache venga salvata sulla mermoria del server web, non vedo come potrebbero migliorare le prestazioni


Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

se intendi la cache del browser ovvio che immagini e quant'altro vengono cachati sul client altrimenti per tutto il resto se ne occupa il server che processa la richiesta

Andrea Restucci - Web Developer

andrestu Profilo | Expert

"cachati" = dati messi in cache
hi hi hiiiii
ho coniugato una nuova parola...

Andrea Restucci - Web Developer

trinity Profilo | Guru

oddio mi sto perdendo...scusate tra febbre ed altro sto funso...facciamo i passi da perfetto ignorante in materia...allora l'utente sulla pagina di ricerca inserisci i parametri, con una querystring li passo alla second apagina che elabora il codice sotto riportato:

Dim lista As List(Of PropertyUtente) = Loadsearch.Search(_str1, _str2)
Cache("result") = lista
RadListView1.DataSource = lista
RadListView1.DataBind()

ora nella cache c'è l'oggetto result ma nella cache del pc locale o del server web?
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

trinity Profilo | Guru

oddio mi sto perdendo...scusate tra febbre ed altro sto funso...facciamo i passi da perfetto ignorante in materia...allora l'utente sulla pagina di ricerca inserisci i parametri, con una querystring li passo alla second apagina che elabora il codice sotto riportato:

Dim lista As List(Of PropertyUtente) = Loadsearch.Search(_str1, _str2)
Cache("result") = lista
RadListView1.DataSource = lista
RadListView1.DataBind()

ora nella cache c'è l'oggetto result ma nella cache del pc locale o del server web?
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

nella cache del server web!!! in quel caso la cache del browser non centra nulla.
La cache del browser non ne sa niente di quello che succede lato server, al massimo il browser può far la cache della pagina che gli arriva renderizzata.
Considera il fatto che alcuni controlli datasource di aspnet implementano un meccanismo di cache che per default se non erro dovrebbe essere disabilitato, comunque nel tuo esempio vedo che associ direttamente l'origine dati al controllo che li visualizza quindi fai bene ad implementare un meccanismo di cache.
Così però per come lo hai scritto a mio avviso non è corretto.

>
>Dim lista As List(Of PropertyUtente) = Loadsearch.Search(_str1,
>_str2)
>Cache("result") = lista
>RadListView1.DataSource = lista
>RadListView1.DataBind()
>

In questo modo stai inserendo la lista in cache, poi associ al datasource la lista direttamente e non prendendola dalla cache, io di solito faccio così, scrivo in C# perchè VB non lo conosco:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

In questo modo sei sicuro al 100% che la lista sarà sempre disponibile in cache, ovvio che il while risulterebbe bloccante qualora ci dovessero essere problemi di qualsiasi tipo, si può però aggiungere del codice con un conteggio che dopo un tot di tentativi prende i dati direttamente dal db oppure altro non so questo dipende da te.

e per ultimo:

%@ OutputCache duration="10" VaryByParam="string1,string2" %>..

questa è una direttiva di pagine che serve a far la cache della pagina renderizzata così a seguito di più richieste uguali viene 'servita' la pagina che si trova in cache invece di ricostruirla ogni volta, i parametri servono appunto a gestirla in base ai parametri stessi, sinceramente questa è un tipo di cache che non ho mai utilizzato, dovrebbe portare dei vantaggi ai tempi di risposta, hai riscontrato dei vantaggi nell'utilizzarla???



Andrea Restucci - Web Developer

trinity Profilo | Guru

Ciao buongiorno e grazie della tua risposta....andiamo in ordine...il mio scopo per l'utilizzo della cache sta nel fatto di avere tempi di risposta delle pagine + velocemente e pertanto dato che posso essere effettuate diverse richieste sulla stessa pagina invece di ricreare connessione al db e pagina ho pensato all'utilizzo della cache e quindi avere maggiori prestazioni in termini di velocità per quanto riguarda la visualizzazione dei dati ecco perchè speravo che venisse utilizzata la cache del client. Ma se centinaia di utenti contemporaneamente dovessero utilizzare il mio servizio di ricerca, non crea problemi al server gestire tutto in cache? In pratica ho fatto una sorta di mini motore di ricerca nell'ambito catena di cooperative e ci sono centinaia di persone che possono fare allo stesso tempo diverse ricerche utilizzando la stessa pagina web (stile google :-) ) e quindi il mio scopo è che quando ottengo i risultati, distribuiti anche per pagina (quindi utilizzo un datapager) non voglio che si venga sempre ad utilizzare la connessione al db, questa solo se cambiano i parametri di ricerca.

Adesso tornando al codice che mi hai postato, che codice potrei inserire per ovviare al fatto che il ciclo while potrebbe essere bloccato?

riassemblando il mio codice con le tue migliorie il risultato sarebbe questo?


Public Function GetLista() As IList(Of PropertyUtente) Dim lst As IList(Of PropertyUtente) = TryCast(Cache("result"), IList(Of PropertyUtente)) While lst Is Nothing Cache("result") = Loadsearch.Search(_str1, _str2) lst = TryCast(Cache("result"), IList(Of PropertyUtente)) End While Return lst End Function RadListView1.DataSource = lst RadListView1.DataBind()

per quanto riguarda questo codice:

%@ OutputCache duration="10" VaryByParam="string1,string2" %>..

pensavo di aver capito leggendo in rete che fino a quando non scade la durata impostato da me o fino a quando non cambiano i valori passati nelle variabili indicate, l'utente utilizzasse i dati salvati in cache senza dover ricorre alla connessione al db...quindi il codice che mi hai postato con questo codice di outputcache possono essere utilizzati entrambi...

Faccio un esempio banale per capire meglio:

supponiamo che io voglio ricercare la parola: anguria. L'utente esegue la ricerca, essendo la prima volta il programma si connette al db preleva i dati li passa in cache e li far vedere a video all'utente, essendo molti dati la pagina è progettata come fa google a far vedere i primi 10 risultati e poi gli altri devono essere sfogliati. Ora il mio scopo è la velocità e soprattutto evitare di ripetere la chiamata al database se l'utente deve solo vedere i dati relativi alla parola "Anguria" quindi secondo la mia logica passo tutti i dati in cache così anche quando deve sfogliare le altre pagine i dati non vengono presi dal db. Fin qui ragione bene? Poi io voglio e qui subentrava il codice (%@ OutputCache duration="10" VaryByParam="string1,string2" %>..) che se l'utente non vuole più ricercare la parola anguria allora cambiando uno dei parametri, avviando la ricerca deve essere effettuata la connessione al database di nuove e ripetere l'iter di riempire la cache con i nuovi dati. Oppure se scade il tempo della cache (impostata da me) ripetere la connessione al db. Giusto tutto questo? Quindi ricapitolando...con il codice che mi hai postato, e con l'aggiunta della stringa html (%@ OutputCache duration="10" VaryByParam="string1,string2" %>..) ottengo questo risultato?

Oppure la parte del codice che te mi hai postato è una cosa mentre questa string OutputCache...svolge un'altra funzione e quindi non possono essere utilizzate entrambe?

Comunque ti ho riassunto il mio problema e quello che vorrei ottenere, se mi puoi dare qualche consiglio te ne sarei grato

ciao e grazie mille dell'aiuto

Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

> Ma se centinaia di utenti contemporaneamente dovessero utilizzare il mio servizio di ricerca, non crea problemi al server gestire tutto in cache?

be la cahce serve peopositamente a questo, pensa alle due ipotesi:
1- ogni utente richiede i dati - questi dati vengono prelevati ad ogni richiesta dal db e per essere visualizzati devono essere memorizzati anche momentaneamente in memoria sul server, quindi ci sarà un tot di memoria occupata che se lo moltiplichi per ogni utente che fa la richiesta...
2- ogni utente richiede i dati - i dati non vengono prelevati dal db ma si trovano già in memoria

ecco che la seconda ipotesi offre vantaggi sia in termini di prestazioni che di occupazione della memoria, ovvio che diventa più difficile gestire il tutto perchè ti devi occupare dei casi in cui i dati vengono modificati su db, la cache risulterebbe non aggiornata, considera che a tal riguardo l'oggetto cache di aspnet prevede meccanismi di scadenza legati anche alle modifiche del db diciamo che è stato progettato proprio a tale scopo quindi ti consiglio di andare ad approfondire l'argomento (come da suggerimento di Alex).
Personalmente io non sfrutto il 100% del potenziale che tale oggetto può dare, e cioè io memorizzo semplicemente i dati in cache e poi ad ogni modifica su db aggiorno manualmente il contenuto della cache di riferiemento, e questo non è molto "intelligente" visto che si potrebbero sfruttare i meccanismi dell'oggetto cache in relazione al db, è comunque una cosa che farò...

> Adesso tornando al codice che mi hai postato, che codice potrei inserire per ovviare al fatto che il ciclo while potrebbe essere bloccato?

be non so io per ora lo sto utilizzando così, però pensavo magari di mettere un int = 0 all'esterno del while e aumentare di 1 all'interno del while, e sempre all'interno del while fare un controllo che se la variabile int arriva ad un tot (per esempio 10) mi esce dal ciclo e mostra un messaggio di errore...

> %@ OutputCache duration="10" VaryByParam="string1,string2" %>..

forse stai facendo un pò di confusione, questa riguarda solo ed esclusivamente l'output del rendering della pagina e non centra con l'oggetto cache, praticamente quando il client fa la richiesta il "motore" aspnet gli fornisce la pagina già "renderizzata" in cache invece di ricostruirla ogni volta, i vari parametri servono appunto nel caso in cui la pagina non è statica ma dinamica e cioè per esempio un interrogazione di dati fornirà molto probabilmente risultati diversi e quindi pagine di tipo diverso, ecco che dunque se i parametri cambiano la cache viene rigenerata.

Alla fine devi utilizzare entrambi i metodi solo che per quanto riguarda la cache dell'output della pagina devi fare attenzione perchè per le pagine dinamiche (per esempio pagine che possono dare risultati diversi in base ai parametri di una ricerca ) se non è impostata correttamente potresti peggiorare le prestazioni invece di migliorarle.

pensa al caso in cui io ho un pagina che può fornire molti risultati diversi di output e inserisco la direttiva
%@ OutputCache... (senza impostare altri parametri)
ad ogni richiesta Aspnet costruirà la pagina e la inserirà in cache perchè i risultati saranno sempre diversi, quindi tutti i vari parametri della direttiva OutputCache servono appunto a creare una regolazione specifica, comunque in merito a questo non sono molto esperto, dovresti andare ad approfondire l'ergomento, anzi se approfondisci sul MSDN fammi sapere...






Andrea Restucci - Web Developer

trinity Profilo | Guru

Ora mi è più chiara la cosa grazie mille...ricapitolando i dati in cache servono a velocizzare il risultato perchè non c'è interrogazione sul db a parte se non cambiano i parametri di ricerca, mentre 'outputcache serve a riproporre una pagina in cache senza doverla ogni volta rigenerare....per evitare che si siano complicazioni si inserisco i parametri per far si che se ci sono dei cambiamenti della ricerca allora la pagina deve essere rigenerata e non presa in cache.

Faccio dei test utilizzando anche oytputcache e ti aggiorno....

Ci sentiamo presto ;-)

Grazie

Ps non chiudo per ora il post perchè vorrei prima darti i miei risultati dopo i test svolti
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

mexico77 Profilo | Junior Member

Volendo puoi anche scegliere dove memorizzare la chache, se su server o sul client... basta aggiungere Location=Client o Server
www.setteweb.it

trinity Profilo | Guru

Veramente anche su client e Location=Client posso passarlo anche tramite code behind oppure solo in html?
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

mexico77 Profilo | Junior Member

anche tramite code...
www.setteweb.it

trinity Profilo | Guru

Scusa ma tramite code come devo scrivere perchè non ho trovato la proprietà location...io in code per aggiungere dei dati in cache faccio per esempio così:

cache("prova")=sorgente dati
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

mexico77 Profilo | Junior Member

Nella direttiva <%@ OutputCache Duration="300" varyByParam="None" Location="Client" %>
www.setteweb.it

trinity Profilo | Guru

Stavo facendo dei test delle prove e mi sto perdendo in un bicchiere d'acqua...scusate se sono ripetitivo ma voglio capire bene....andiamo per step...
Il mio obbiettivo primario e rendere la pagina + veloce possibile nel visualizzare i dati ma anche il rendering della pagina stessa..
Per quanto riguarda la memorizzazione dei dati e la sua visualizzazione avevo trovato in rete su questo link: http://www.mrwebmaster.it/aspnet/guide/caching-dati_1246.html la spiegazione ad usare con aspnet valori situati nella cache..
Cioè l'articola cita che se si utilizza abitualmente degli stessi dati per evitare di riconnettersi al db allora si può utilizzare i valori salvati in cache.
Pertanto se ho capito bene l'articolo, prendendo il mio caso, io nella pagina scrivo il parametro da ricercare, controllo se in cache ci sono i parametri, se non ci sono effettuo la connessione al db e poi passo i parametri alla cache, se invece ci sono utilizzo la cache direttamente...

Ecco l'esempio reale del mio codice:

ho questa funzione di ricerca:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

e poi alla listview carico il dato in questa maniera:

RadListView1.DataSource = Cache("risultati") RadListView1.DataBind()

adesso prima di tutto è giusto come gestisco la cache dei dati? secondo supponiamo che cerco la parola "roma" e quindi in cache "risultati" si andranno a salvare tutti i record inerenti a "roma", supponiamo che dopo volessi ricercare "firenze", adesso con questo metodo i record che riguardano firenze si vanno a sovrascrivere a quelli di roma in cache o vengono aggiunti, il che vuol dire che se dovessi ricercare di nuovo "roma" si andrebbe ad utilizzare la cache sempre...
Poi arriviamo alla gestione della cache local o su server...con la tecnica che sopra ho scritto la cache viene salvata sul server web oppure in locale?
Ovviamente dovrei inserire come giustamente ha scritto maxico questa stringa nella parte html: <%@ OutputCache Duration="300" varyByParam="text1" Location="Client" %> e così andrei a salvare in locale ma salvo il locale il rendering della pagina o i dati che ho gestito in cache con la procedura di prima? è qui che mi perdo un attimo...
Terzo è meglio salvare in locale o su server web?
Quarto e se non dovessi specificare un parametro ma bensì indicare solamente questa stringa: <%@ OutputCache Duration="300" varyByParam="none" Location="Client" %>, calcolando che la pagina può essere visualizzata contemporaneamente da moltissime persone, andrebbe a creare problemi a livello di prestazioni oppure no, visto che la cache si pulisce solo attraverso la sua durata?

ciao e scusatemi ancora se torno su questo argomento, voglio solo capire bene il tutto

ciao
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

allora per quanto riguarda la cache lato server dei dati, cioè quelli che prelevi da db l'importante e che segui questo pattern poi il modo in cui lo implementi può essere del tutto personalizzato:

preso dalla pagina che hai indicato:
- Verificare se un determinato dato si trova in cache
- Se è presente in cache utilizzarlo
- Se non è presente in cache connettersi al database per ottenerlo

ovviamente a questo punto devi decidere cosa mettere in cache, la soluzione più semplice è quella di mettere in cache l'intera tabella di origine dati, dunque se qualche utente fa una ricerca filtrata dovrai implementare un metodo che data una sorgente (la lista che hai in cache) ti restituisce una vista (copia) dei dati filtrata secondo parametri impostati dall'utente (a questo scopo ti consiglio l'uso di LINQ), questo risultato potrà per esempio essere messo in session e quindi l'utente visualizzerà la sua "lista" personalizzata.
Puoi anche cachare oltre alla tabella di base anche o solo i risultati che ritieni più di uso frequente ma questo complica ancor di più lo scenario.

Puoi semplificare ulteriormente facendo così:
1 - crei una classe statica con un metodo GetData che restituisce i dati, all'interno di questa classe ci sarà tutto il meccanismo che controlla se i dati sono in cache, in caso contrario li prende dal DB e li mette in cache, l'importante è che il metodo GetData restituisce tutti i dati non filtrati.
2- a questo punto per semplificare la gestione del filtraggio puoi usare un controllo ObjectDataSource configurato con:
...TypeName = typeof(NomeTuaClasseCheFornisceIdati).FullName;
...SelectMethod = "GetData";
poi ti leggi un pò di documentazione a riguardo ObjectDataSource vedrai che fornisce meccanismi di facile utilizzo per legare il controllo ai parametri di filtro, diciamo che pensa a tutto il controllo in questione, data la lista di origine ti restituisce una lista filtrata secondo i parametri da te indicati nella configurazione del controllo.







Andrea Restucci - Web Developer

trinity Profilo | Guru

Aspetta...nella pagina dove l'utente esegue la ricerca è vuota con un campo di ricerca quindi in base al parametro che il cliente passa io eseguo una function all'interno di essa una stored per selezionare tutti i record che soddisfano il parametro dell'utente ed io vorrei mettere in cache tale risultato in modo tale che se il cliente dovesse rifare la stessa ricerca lo trova già in cache, giusta come logica?

a questo punto te mi ha detto di creare una classe getdata e passarla alla cache allora questo codice che io utilizzo e che posto non va bene?

Public Function Search(ByVal _Str1 As String, ByVal _Str2 As String) As List(Of PropertyUtente)
Using scope As New TransactionScope()
Dim lista As New List(Of PropertyUtente)
If Cache("risultati") Is Nothing Then
Dim conString = ConfigurationManager.ConnectionStrings("TrycontactString")
Dim strConnString As String = conString.ConnectionString
Using db As New SqlConnection(strConnString)
db.Open()
Using sqlcmd As New SqlCommand("Sp_searching_like", db)
sqlcmd.CommandType = CommandType.StoredProcedure
sqlcmd.Parameters.AddWithValue("@Search", SqlDbType.VarChar).Value = _Str1
sqlcmd.Parameters.AddWithValue("@Searchluogo", SqlDbType.VarChar).Value = _Str2
Using sqldr As SqlDataReader = sqlcmd.ExecuteReader
While sqldr.Read
Dim _image As String
If sqldr.GetSqlString(6).IsNull = True Then
_image = "/image/avatarborder.png"
Else
_image = sqldr.GetSqlString(6).Value
End If
Dim recapiti As String = ""
If (sqldr.GetSqlValue(4).IsNull = True Or sqldr.GetSqlValue(4).ToString = String.Empty) And (sqldr.GetSqlValue(5).IsNull = True Or sqldr.GetSqlValue(5).ToString = String.Empty) Then
recapiti = "Non disponile"
ElseIf sqldr.GetSqlValue(4).IsNull = False And (sqldr.GetSqlValue(5).IsNull = True Or sqldr.GetSqlValue(5).ToString = String.Empty) Then
recapiti = sqldr.GetSqlValue(4).Value
ElseIf (sqldr.GetSqlValue(4).IsNull = True Or sqldr.GetSqlValue(4).ToString = String.Empty) And (sqldr.GetSqlValue(5).IsNull = False) Then
recapiti = sqldr.GetSqlValue(5).Value
ElseIf sqldr.GetSqlValue(4).IsNull = False And sqldr.GetSqlValue(5).IsNull = False Then
recapiti = sqldr.GetSqlValue(4).Value & " - " & sqldr.GetSqlValue(5).Value
End If
lista.Add(New PropertyUtente With {.idutente = sqldr.GetSqlInt32(0).Value, _
.utente = sqldr.GetSqlString(1).Value.ToUpper.ToUpper, _
.Desccategoria = sqldr.GetSqlString(2).Value, _
.Desccomune = sqldr.GetSqlString(3).Value, _
.Telefono = recapiti, _
.Imageprofile = _image, _
.Email = sqldr.GetSqlString(7).Value})
End While
End Using
End Using
End Using
End If
Cache("risultati") = lista
Return lista
scope.Complete()
End Using
End Function

io qui faccio il controllo se la cache "risultati" è vuota, se lo è prendo i dati dal db se invece è piena non li prendo e gli passo al risultato della function il valore che ho nella cache..tale function è connesso all'oggetto radlistview (utilizzo gli oggetti telerik) e per caricare i dati passo questa function al datasource dell'oggetto listview.

te citi che la soluzione ideale sarebbe quella di mettere in cache l'intera tabella di origine dati, dunque se qualche utente fa una ricerca filtrata dovrai implementare un metodo che data una sorgente (la lista che hai in cache) ti restituisce una vista (copia) dei dati filtrata secondo parametri impostati dall'utente. Il discorso come ti ho scritto sopra che io ottengo già dalla prima chiamata al database un risultato filtrato quindi mi viene da pensare che per quello che mi serve a me la cache non serve...

guarda forse è meglio che vedi il mio progetto.... vai su questo sito: www.trycontact.com, il ho gestito in questo sito...in pratica è un sito dove si possono iscrivere qualsiasi attività o liberi professionisti...allora sulla home page ci sono i parametri di ricerca se esempio nella città scrivi "terracina" ti appariranno i record di riferimento....ok ovviamente in basso della pagina di risultato c'è anche il pager per andare vanti o indietro nello sfoglio delle pagine..diciamo un pò stile google ;)..Adesso io vorrei che il risultato della ricerca venga messo nella cache perchè se te poi vorresti fare un'altra ricerca più dettagliata e nell'ambito della città di terracina vuoi vedere tutti gli ingegneri allora per evitare che avvenga di nuovo una chiamata al db data che nella cache ci sono già tutti i record di terracina volevo che l'ulteriore filtraggio avvenisse all'interno della cache per rendere + veloce il tutto....Sbaglio come logica oppure no?
Alla fine ma google come fai ad avere una ricerca così veloce? oltre che ovviamente ad avere server potenti ed altro, ma non sfrutta anche lui la cache secondo te?

Ciao
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

guarda se vuoi mettere in cache risultati specifici allora devi creare un metodo che in base ai paramteri passati ti prenda dalla cache la lista giusta già filtrata, però fai attenzione che se i risultati diventano molti riempi di dati la cache, invece come ti suggerivo io riempi la cache con la tabella master e poi tutti i relativi risultati vengono salvati in session così quando l'utente chiude il browser la memoria viene liberata.
In questo modo hai già un vantaggio evitando di far fare ogni volta la richiesta al db per ogni utente, se però vuoi salvare risultati specifici allora devi studiarti un meccanismo adatto il che non è molto semplice.
Se invece vuoi evitare tutto questo usa il controllo SqlDataSource e attiva la cache sul controllo, pensa lui a gestire il tutto...

Andrea Restucci - Web Developer

trinity Profilo | Guru

Ciao,
caricare l'intera tabella master con tutti i dati vuol dire una marea di possibili dati in quanto devo calcolare che ci possono essere anche migliaia di record e se fosse penso che se dovessi caricare tutto la pagina diventerebbe lenta prima che si apra, giusto? ossia questa tabella che mi dici di caricare quando dovrei caricarla, quando vado ad aprire il sito o la pagina di ricerca? Lo scopo mio della cache era di velocizzare ancora di più la ricerca dei record da parte degli utenti anche se nel caso ci fosse simultaneamente decine di utenti che sfruttano la ricerca per cercare qualcosa.
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

e allora se prevedi che possa essere troppo grande salvati solo i risultati delle ricerche, il fatto è che devi scrivere del codice che sia in grado in base ai parametri scelti di restiutire la lista interessata, non so se l'oggetto cache fornisca già di suo qualche meccanismo di sincronizzazione con parametri specifici, non credo, in tal caso una soluzione potrebbe essere quella di creare una stringa personalizzata in base appunto ai parametri, e usare questa stringa come valore chiave della cache per il recupero delle liste, ogni stringa si riferirà ad una lista differente.
Per quanto riguarda il quando salvare la cache a questo punto io lo farei al momento della richiesta, nel senso che quando un utente richiede una certa lista ci sarà del codice che controlla se esiste in cache, in caso contrario prende i dati dal db e li metti in cache usando una certa logica per la chiave.
Non so se mi sono spiegato, per esempio l'utente Pippo richiede dei dati filtrati per solo la città di Roma, a questo punto all'interno del GetData metti del codice che controlla se in cache esiste la lista:

CR in questo caso sta per Città Roma (questa potrebbe essere un idea di logica per la chiave ma puoi cambiarla come meglio credi)
if(Cache["CR"] != null)
{
... restituisci la lista
}
else{
... prendi i dati dal db e li metti in cache dopodichè restituisci la lista appena messa in cache
}

Non devi caricare anticipatamente tutte le liste possibili altrimenti è tutto inutile, in questo modo la cache si riempirà man mano di liste legate alle possibili richieste e quando la memoria sarà piena l'oggetto cache in automatico si occuperà di eliminare le liste meno richieste. Se però le richieste sono molte differenti con parametri differenti devi prendere in considerazioni il fatto che invece di migliorare le prestazioni potresti peggiorarle perchè praticamente ad ogni richiesta l'oggetto cache si troverebbe costretto a svuotare e riempire in aggiunta al carico dato per il prelievo dei dati sul db, questo dipende anche dalla memoria che l'hosting ti mette a disposizione, se non usi un server dedicato allora potresti avere problemi.

Per esempio io di recente ho sviluppato questo sito http://www.piazzaaffariimmobiliare.it seguendo la logica che ti ho esposto nei post precedenti, carico i dati in cache quando vengono richiesti e poi con LINQ restituisco le liste filtrate che vengono momentaneamente salvate in session, quindi il carico di lavoro verso il database è praticamente azzerato, il fatto è che così comè implementato sarebbe una scheggia se il sito fosse messo su un server dedicato, invece per ragioni varie sono stato costretto a metterlo su Register servizio base, e ogni tanto noto un calo drastico di prestazioni che non so di preciso a cosa imputare, potrebbe essere la mancanza di memoria come anche la ridotta capacità di banda.
In locale ho notato che i dati in memoria non occupano molto (non uso datatable ma semplici oggetti mappati con ADONET tramite un datareader) e devo ammettere che brancolo un pò nel buoi, come primo passo dovrei fare una stima dell'occupazione di memoria magari replicando il db in locale...




Andrea Restucci - Web Developer

trinity Profilo | Guru

Ho capito io il mio sito si trova su aruba ma è anche vero che se dovesse andare prendo un server dedicato...adesso il dubbio è quello che mi hai detto sul fatto che se ci sono moltissime richieste alla fine potrei andare a peggiorare perché la cache deve svuotare e aggiornare nel caso in cui sia piena..giusto? ma non esiste proprio un modo per evitare questo intoppo oppure non c'è un modo di svuotare una parte della cache e quindi lasciarla sempre libera in parte da ottenere sempre prestazioni elevate...per esempio quando si apre l'home page si controlla se la cache è piena e viene in parte liberata in modo tale che quando l'utente esegue una ricerca la cache è già libera per accettare nuovi dati...

Altra cosa che ho visto nel tuo sito, sulla home tua come fai a caricare quelle slide degli appartamenti? in maniera così veloce? io ho fatto questa pagina è in test quindi non è online ufficiale: www.trycontact.com/pindex.aspx...in pratica ogni persona che si è registrata in maniera random appare sulla home page..quindi ho creato sul load della pagina una connessione al db che esegue una query con top 8...e spara i dati in una listview..poi ho aggiunto un timer che ogni 30 sec aggiorna in maniera random la visualizzazione del card...ecco il problema è solo al primo caricamento della pagina che esegue la connessione ed impiega un po' di tempo a visualizzare la stessa pagina..esiste un modo per velocizzare il tutto secondo te. oppure per esempio una tecnica che mi fa caricare velocemente la pagina così l'utente non vede che è lenta e poi successivamente si caricano le card random, spero di essermi spiegato..se vedi la pagina te ne accorgi.

ciao
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

non mi sembra così lenta la tua pagina, comunque la prima cosa che degrada le prestazioni dovrebbe essere appunto la connessione al db quindi cerca di farne fare meno possibili usando la cache. Sinceramente capire come e quanto usarla non avendo un server dedicato è arduo compito, bisognerebbe sapere prima di tutto quanta memoria mette a disposizione un hosting di base come quello da noi usato e poi fare una stima del consumo di memoria in base ai dati esistenti sul db (comunque anche io per il mio progetto avrei preferito Aruba solo che ho voluto accontentare il cliente).
Per quanto riguarda la mia pagina Home considera che tutti i dati sia di quella pagina che delle altre vengono messi in cache, quindi attualmente ho pochi record di immobili ma ho anche tutte le regioni-provincie-comuni d'Italia. se però i record dovessero aumentare in maniera esponenziale chissà...
Altra cosa che ci sarebbe da capire è se la memoria usata dall'hosting è la stessa sia per la cache che per la session, per esempio io i risultati delle ricerche effettuate nella pagina vetrina li salvo in session quindi se il serve gestisce le memorie separatamente allora al massimo se occupo troppa memoria mi scade la session, ma questa è solo un ipotesi non ho verificato, anzi molto probabilmente non sarà così, e comunque alla fine per progetti importanti secondo me cè solo da avere un server dedicato a tanti saluti e grazie, almeno riesci a renderti conto personalmente dell'occupazione di memoria, magari un bel Cloud così se il progetto decolla allora basta aumentare la config hardware.
Nel tuo caso non saprei, se la ricerca ha come minimo parametro di filtro la città allora potresti suddividere i dati in cache per città, quindi Cache["Roma"] Cache["Genova"] e così via, in questo modo hai una lista per ogni provincia e se la memoria occupata diventa troppo in automatico vengono eliminate le liste delle provincie poco richieste, oppure forse ancor meglio suddividi per regione, mi sembra un buon compromesso

Andrea Restucci - Web Developer

trinity Profilo | Guru

>non mi sembra così lenta la tua pagina, comunque la prima cosa
>che degrada le prestazioni dovrebbe essere appunto la connessione
>al db quindi cerca di farne fare meno possibili usando la cache.
ma su quella home page purtroppo io devo far girare random dei banner quindi la connessione al db deve avvenire per forza. Ora esiste una tecnica che permette di far apparire la pagina e poi successivamente far avviare la connessione al db e quindi prendere i record e visualizzarli a video? Esempio evitare che nella page_load della index avvenga la connessione al db e con un thread esempio farla partire successivamente alla sua visualizzazione..

>Sinceramente capire come e quanto usarla non avendo un server
>dedicato è arduo compito, bisognerebbe sapere prima di tutto
>quanta memoria mette a disposizione un hosting di base come quello
>da noi usato e poi fare una stima del consumo di memoria in base
>ai dati esistenti sul db (comunque anche io per il mio progetto
>avrei preferito Aruba solo che ho voluto accontentare il cliente).
>Per quanto riguarda la mia pagina Home considera che tutti i
>dati sia di quella pagina che delle altre vengono messi in cache,
>quindi attualmente ho pochi record di immobili ma ho anche tutte
>le regioni-provincie-comuni d'Italia. se però i record dovessero
>aumentare in maniera esponenziale chissà...
>Altra cosa che ci sarebbe da capire è se la memoria usata dall'hosting
>è la stessa sia per la cache che per la session, per esempio
>io i risultati delle ricerche effettuate nella pagina vetrina
>li salvo in session quindi se il serve gestisce le memorie separatamente
>allora al massimo se occupo troppa memoria mi scade la session,
>ma questa è solo un ipotesi non ho verificato, anzi molto probabilmente
>non sarà così, e comunque alla fine per progetti importanti secondo
>me cè solo da avere un server dedicato a tanti saluti e grazie,
>almeno riesci a renderti conto personalmente dell'occupazione
>di memoria, magari un bel Cloud così se il progetto decolla allora
>basta aumentare la config hardware.
I server Cloud mi spieghi cosa hanno in più di server dedicati?
Comunque hai ragione se il progetto decolla c'è bisogno di un server dedicato e semmai i dati sono molti passare all'utilizzo anche dei database non relazionali i famosi Nosql (io sto iniziando a vedere come funziona MongoDb, che gira tranquillamente con visual studio oppure RavenDb)
>Nel tuo caso non saprei, se la ricerca ha come minimo parametro
>di filtro la città allora potresti suddividere i dati in cache
>per città, quindi Cache["Roma"] Cache["Genova"] e così via, in
>questo modo hai una lista per ogni provincia e se la memoria
>occupata diventa troppo in automatico vengono eliminate le liste
>delle provincie poco richieste, oppure forse ancor meglio suddividi
>per regione, mi sembra un buon compromesso
La mia ricerca si basa su due campi ossia sul primo si può scrivere la categoria che vuoi cercare oppure il nome, mentre sul secondo campo la città...quindi ci possono essere i seguenti casi di ricerca:
cerco tutti i record della città di roma quindi scrivo il parametro nel campo città, oppure voglio ricercare tutte le pizzerie di roma, quindi nel campo Nome/categoria ci scrivo pizzeria e nel campo città ci scrivo roma. come vedi le ipotesi possono essere molteplici, quindi dubito che io possa utilizzare la cache a questo punto o sbaglio? Semmai la cache potrei utilizzarla quando si apre la propria scheda personale, la prima volta la carico dal db la seconda da cache visto che tanto è sempre la stessa.

>
>Andrea Restucci - Web Developer

Ciao
Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

>ma su quella home page purtroppo io devo far girare random dei banner quindi la connessione al db deve avvenire per forza. Ora esiste una tecnica che permette di far apparire la pagina e poi successivamente far avviare la connessione al db e quindi >prendere i record e visualizzarli a video? Esempio evitare che nella page_load della index avvenga la connessione al db e con un thread esempio farla partire successivamente alla sua visualizzazione..

la logica è sempre la stessa applicata a qualsiasi contesto, ovvio che se usi la cache devi evitare la connessione diretta al db da client

>I server Cloud mi spieghi cosa hanno in più di server dedicati? ...
a quanto ho capito se non sbaglio puoi aumentare le risorse hardware senza dover sostiutire appunto il server intero e paghi in base all'effettivo consumo delle risorse, quindi te puoi partire con una configurazione base per aumentare man mano nel caso in cui hai bisogno di più risorse

> come vedi le ipotesi possono essere molteplici, quindi dubito che io possa utilizzare la cache a questo punto o sbaglio?
potresti allora caricare in cache la tabella intera suddivisa in parti, per farti un esempio in Cache["MiaTabella5000"] andrò a salvare i primi 5000 record , Cache["MiaTabella10000"] dai 5000 ai 10000, Cache["MiaTabella15000"] .... il punto e che devi crearti del codice ad hoc che risponde alle richieste andando a cercare in tutte le cache interessate il dato richiesto, però in questo caso sarebbe opportuno l'utilizzo di LINQ perchè per esempio se a seguito di una ricerca ne risultano ho un tot di record della prima cache e un tot della seconda o terza devi prenderli tutti e unirli in un unica tabella per poi restituirla come risultato...




Andrea Restucci - Web Developer

trinity Profilo | Guru

>>ma su quella home page purtroppo io devo far girare random dei banner quindi la connessione al db deve avvenire per forza. Ora esiste una tecnica che permette di far apparire la pagina e poi successivamente far avviare la connessione al db e quindi >prendere i record e visualizzarli a video? Esempio evitare che nella page_load della index avvenga la connessione al db e con un thread esempio farla partire successivamente alla sua visualizzazione..
>
>la logica è sempre la stessa applicata a qualsiasi contesto,
>ovvio che se usi la cache devi evitare la connessione diretta
>al db da client

Aspetta qui non ti seguo.. La prima volta che l'utente accede alla pagina, per visualizzare i dati la stessa pagina deve per forza eseguire la connessione al db e quindi la prima volta la pagina risulta pesante da caricare, se poi metto in cache quei dati, la prossima volta che l'utente si ricollega apre i dati in cache, ovviamente la mia pagina con il timer aggiorna ogni 30 sec i record visualizzati il che vuol dire che se metto in cache i dati del db, la prima volta che si connette un utente, significa che ogni volta che l'utente aprirà la pagina partirà sempre con quei soliti dati caricati in cache e quindi non vedrà mai i nuovi banner pubblicati. Dove mi sono onestamente perso ora è capire come far fare la connessione al db dopo l'avvenuta visualizzazione della pagina o meglio dopo il rendering della pagina.

>> come vedi le ipotesi possono essere molteplici, quindi dubito che io possa utilizzare la cache a questo punto o sbaglio?
>potresti allora caricare in cache la tabella intera suddivisa
>in parti, per farti un esempio in Cache["MiaTabella5000"] andrò
>a salvare i primi 5000 record , Cache["MiaTabella10000"] dai
>5000 ai 10000, Cache["MiaTabella15000"] .... il punto e che
>devi crearti del codice ad hoc che risponde alle richieste andando
>a cercare in tutte le cache interessate il dato richiesto, però
>in questo caso sarebbe opportuno l'utilizzo di LINQ perchè per
>esempio se a seguito di una ricerca ne risultano ho un tot di
>record della prima cache e un tot della seconda o terza devi
>prenderli tutti e unirli in un unica tabella per poi restituirla
>come risultato...
potrebbe essere una soluzione ma caricare la tabella intera vuol dire che almeno una volta l'utente quando apre la pagina di ricerca deve attendere il caricamento di tutti i record? quindi almeno pe runa volta ci sarebbe una lentezza mostruosa...Oppure c'è un altro modo per fare questo ossia carica la tabella in cache senza che l'utente debba attendere molto?

>
>
>
>
>Andrea Restucci - Web Developer

Cirillo Fabio
www.trycontact.com
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

andrestu Profilo | Expert

>Aspetta qui non ti seguo.. La prima volta che l'utente accede
>alla pagina, per visualizzare i dati la stessa pagina deve per
>forza eseguire la connessione al db e quindi la prima volta la
>pagina risulta pesante da caricare, se poi metto in cache quei
>dati, la prossima volta che l'utente si ricollega apre i dati
>in cache, ovviamente la mia pagina con il timer aggiorna ogni
>30 sec i record visualizzati il che vuol dire che se metto in
>cache i dati del db, la prima volta che si connette un utente,
>significa che ogni volta che l'utente aprirà la pagina partirà
>sempre con quei soliti dati caricati in cache e quindi non vedrà
>mai i nuovi banner pubblicati. Dove mi sono onestamente perso
>ora è capire come far fare la connessione al db dopo l'avvenuta
>visualizzazione della pagina o meglio dopo il rendering della
>pagina.

forse stai facendo confusione, la cache è condivisa nell'intera applicazione, quindi tutte le sessioni degli utenti se richiamano Cache["MiaLista"] avranno restituita la stessa lista per tutti, quindi se la cache è vuota e un l'utente "1" apre la pagina e riempe dunque la cache con Cache["MiaLista"] e subito dopo utente "2" da un altro pc apre la stessa pagina e richiama Cache["MiaLista"] la troverà piena... la troverà vuota solo se tra la richiesta dell'utente 1 e quella dell'utente 2 il server fa il riavvio dell'Application

>potrebbe essere una soluzione ma caricare la tabella intera vuol
>dire che almeno una volta l'utente quando apre la pagina di ricerca
>deve attendere il caricamento di tutti i record? quindi almeno
>pe runa volta ci sarebbe una lentezza mostruosa...Oppure c'è
>un altro modo per fare questo ossia carica la tabella in cache
>senza che l'utente debba attendere molto?

ma questo dipende da come progetti il sito, potresti anche precaricare in cache i dati il Application_Start solo che se i dati sono molti non so se sia molto sensato, la cache è studiata appositamente per eliminare gli elementi meno utilizzati (se inseriti in maniera diretta tipo Cache["mialista"]) in caso di scarsa memoria , quindi ammettiamo che tu precarichi in Application_Start tutta la cache e i dati sono più di quanta memoria l'hosting rende disponibile, succede questo:

Cache["lista1"] = ...
Cache["lista2"] = ...
Cache["lista3"] = ...
Cache["lista4"] = ...
Cache["lista5"] = ...
Cache["lista6"] = ...
Cache["lista7"] = ...
Cache["lista8"] = ...
- fine della memoria disponibile
- eliminazione da parte della cache di "lista1"
Cache["lista9"] = ...
- fine della memoria disponibile
- eliminazione da parte della cache di "lista2"
Cache["lista10"] = ...
- fine della memoria disponibile
- eliminazione da parte della cache di "lista3"

hai capito cosa intendo? potresti comunque farlo qualcosa sicuramente in cache ti ritrovi, e comuqne visto che inizialmente non hai molti dati e l'obbiettivo è quello di velocizzare al massimo puoi farlo...









Andrea Restucci - Web Developer
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5