problema wcf accessi contemporanei
-
Thursday, November 12, 2009 5:25 PM
Ciao a tutti!
la mia applicazione WCF / ASP.NET manifesta un problema piuttosto grave (è la prima applicazione che faccio di questo tipo). Una decina di magazzinieri accedono più o meno contemporaneamente al database access, consultano e modificano le proposte d'ordine a loro indirizzate. Quando ci sono più accessi contemporanei ogni tanto capita un fatto increscioso: mentre il magazziniere sta consultando una proposta d'ordine, si ritrova sotto gli occhi la proposta di un altro magazziniere.
L'applicazione è costiuita da 2 parti: un service WCF ospitato su IIS in un computer interno alla rete aziendale con Vista Business com s.o. e un'applicazione ASP.NET ospitata su aruba che interroga il service.
Dato che l'errore si presenta quando l'applicazione ASP.NET chiede al service di trasmettergli una proposta (ne restituisce un'altra), per quel che posso capire le cause possono essere 2: dato che il nome nella proposta è preso da una variabile memorizzata nella cache, può essere che questa variabile venga sovrascritta. Oppure il service WCF quando ci sono più accessi contemporanei impazzisce e trasmette una proposta al posto di un'altra (mi sembra più improbabile).
Potreste aiutarmi a trovare il bandolo della matassa?
Pileggi
Questo è il codice con cui effettuo la richiesta e trasmetto i dati:
LATO APPLICAZIONE ASP.NET (ARUBA)
Private Property VNomePro() As String Get Dim s As String = Cache("VNomePro") Return s End Get Set(ByVal value As String) Cache("VNomePro") = value End Set End Property ' Pro è la collection di dati con la proposta Dim p As Pro = TPclient.TrasmettiPro(VNomePro)LATO SERVICE WCF
' prelevo i dati dal database access Public Function TrasmettiPro(ByVal sPro As String) As Pro _ Implements ITPro.TrasmettiPro Dim p As New List(Of SingleRowPro) Dim srp As SingleRowPro Using cn As New OleDbConnection(sConn) Dim sQuery As String = String.Format("SELECT {0}.* FROM {0} ORDER BY " & _ "{0}.Aggiunta, {0}.Articolo;", sPro) Using cm As New OleDbCommand(sQuery, cn) cn.Open() Using rd As OleDbDataReader = cm.ExecuteReader() While rd.Read() srp = New SingleRowPro srp.Reparto = rd.Item("Reparto") srp.Precodice = rd.Item("Precodice") If Not IsDBNull(rd.Item("Fatto")) Then srp.Fatto = rd.Item("Fatto") srp.Articolo = rd.Item("Articolo") srp.datcon = rd.Item("datcon") If Not IsDBNull(rd.Item("Giacenza")) Then srp.Giacenza = rd.Item("Giacenza") p.Add(srp) '... e così via tutti gli altri dati End While rd.Close() End Using End Using cn.Close() End Using Dim pp As New Pro With {.Proposta = p} Return pp End Function- Moved by Irina TurcuMicrosoft Contingent Staff, Owner Tuesday, November 15, 2011 8:58 AM Spostato thread nel forum più appropriato. (Da:Microsoft ASP.NET Forum)
All Replies
-
Thursday, November 12, 2009 11:15 PMIn mancanza di una soluzione certa, per ora ho provato a cambiare la modalità di memorizzazione della variabili nell'applicazione ASP.NET, prima usavo la cache - Cache("NomeVariabile") - adesso uso il ViewState - ViewState("NomeVariabile"). Soltanto domani potrò sapere se il cambiamento è stato efficace perchè potrò provare più accessi contemporanei. Ma (please) aiutatemi a usare correttamente la cache, in rete si afferma che migliora sensibilmente le prestazioni!
Pileggi -
Friday, November 13, 2009 10:08 AM
Sicuramente il problema è proprio lì. Tieni presente che la cache è condivisa tra tutte le sessioni attive. Ti permette sostanzialmente di memorizzare dati comuni a tutte le sessioni per un più rapido accesso. Per i dati relativi alla sessione utente c'è la Session (in memoria) o il ViewState (memorizzato nella pagina). Quest'ultimo, però, tende spesso a diventare troppo grande, incrementando notevolmente il flusso di dati che viaggia dal browser al server e di conseguenza decrementando le prestazioni.
Spero di esserti stato d'aiuto.
Fabio Cozzolino Blogs: http://dotnetside.org/blogs/fabio http://weblogs.asp.net/fabio- Marked As Answer by pileggi Friday, November 13, 2009 10:44 AM
-
Friday, November 13, 2009 10:39 AMGrazie tante veramente. Vista la tua gentilezza vorrei chiederti ancora 2 cose:
in quali casi è opporuno usare la cache per memorizzare i dati?
il viewstate serializza i dati e li deserializza quando è il momento di leggerli. Questo comporta un calo di prestazioni, se i dati non sono critici, è possibile (e conveniente) salvare i dati senza serializzarli? E possibile serializzare alcui dati e non altri?
Spero non siano troppe domande, avrei bisogno di farmi un'idea più precisa.
Grazie ancora,
Pileggi -
Friday, November 13, 2009 5:18 PM
Il viewstate memorizza i dati serializzati. Il problema non si pone, se la tua classe che metti nel view state non è serializzabile becchi un'eccezione. La cache va utilizzata quando vuoi condividere dati (ma anche pezzi di output HTML) tra gli utenti e far in modo che dopo un certo periodo possano scadere. Il viewstate serve solo per mantenere informazioni tra un post-back ed il successivo. La sessione memorizza info (che non scadono mai finchè la sessione è valida) visibile solo dall'utente che li ha messi. Application memorizza dati visibili da tutti e senza scadenza (almeno fino a che non fai un reset di IIS).- Marked As Answer by pileggi Saturday, November 14, 2009 8:58 AM
-
Saturday, November 14, 2009 8:59 AMGrazie!!
-
Saturday, November 14, 2009 7:32 PM
Conclusione di questo episodio:
la pagina di login passa all'altra pagina la stringa contenente il nome-utente tramite un cookie (è utile perchè resta memorizzato sul browser del client e l'utente non è costretto a riscriverlo ogni volta)
Private Property CUtente() As String
Get
Dim s As String = ""
If Request.Cookies("CUtente") IsNot Nothing Then
If Request.Cookies("CUtente")("Valore") IsNot Nothing Then
s = Request.Cookies("CUtente")("Valore")
End If
End If
CUtente = s
End Get
Set(ByVal value As String)
If Value Is Nothing Then
If Request.Cookies("CUtente") IsNot Nothing Then
Dim myCookie As HttpCookie
myCookie = New HttpCookie("CUtente")
myCookie.Expires = DateTime.Now.AddDays(-1D)
Response.Cookies.Add (myCookie)
End If
Else
Dim myCookie As HttpCookie = New HttpCookie("CUtente")
myCookie("Valore") = Value
myCookie.Expires = Now.AddMonths(12)
Response.Cookies.Add (myCookie)
End If
End Set
End Property
l'altra pagina riceve l'utente dal cookie, lo memorizza nel ViewState e, tramite la stringa-utente memorizzata nel ViewState, crea tutte le altre variabili nella cache assegnandogli una chiave univoca contentente il nome-variabile e la stringa-utente:
Private Property SUtente() As String
Get
Dim s As String = ViewState("SUtente")
Return s
End Get
Set(ByVal value As String)
ViewState("SUtente") = Value
End Set
End Property
Private Property NomeVariabile() As String
Get
Dim s As String = Cache("NomeVariabile" & SUtente)
Return s
End Get
Set(ByVal value As String)
Cache("NomeVariabile" & SUtente) = Value
End Set
End Property
Non so se era la cosa migliore da fare, so che in questo modo si ottiene un miglioramento di prestazioni veramente notevole rispetto a memorizzare tutte le variabili nel ViewState.
Per questo, oltre che per dare com'è giusto conto del risultato dei consigli ricevuti, mi sento, nel mio piccolo, di consigliare a tutti questo metodo.
Ciao!
Pileggi

