Sesija, po difoltu, je podešena na 20 minuta, čini mi se, što znači da ako korisnik ustane od računara, dataset svakako ostaje nedodirljiv za GC dok ne istekne tih 20 minuta.
Citat:
To znači da bi se u praksi (često?) dešavalo da moramo da pravimo nov dataset dok je onaj stari još negde u memoriji.
Vrlo često iz prostog razloga što GC ne trči svaki čas - ovo se odnosi i na desktop aplikacije. Praktično svaki put kada ti podaci zatrebaju (često je dovoljno jednom za jedno povezivanje na stranicu) kreiraš nove objekte iako su stari možda još uvek u memoriji, ali naravno nedostupni, pošto nema referenci koje pokazuju na njih. To što je stari dataset još uvek možda u memoriji je posao o kom GC treba da brine. Kao što desktop korisnik može da otvori i zatvori neku (Windows.Forms) formu 1000x ako hoće.
Mi ionako nemamo mogućnost da definitivno uklonimo objekt iz memorije kada hoćemo, zar ne?
Citat:
Ok, slazem se sa Tatom da referencu na Dataset ne treba drzati u sesiji, a pogotovo je ne treba unistiti, jer kao sto sama rec kaze ona ukazuje na objekat, pa bi se isti "izgubio"...
A gde ćeš je držati ako ne u sesiji, a hoćeš da ponovo ne vršiš upit pri novom pristupu stranici? Application ne dolazi u obzir, a onda ostaje samo još stranica (page scope). A to znači da se referenca uništava čim server pošalje stranicu klijentu.
Kreiranje novog objekta nije strašno (imamo čak i connection pooling, što rešava najčešći problem pri ovakvom radu), a ostavljanje istog bespotrebno u memoriji tokom čitave sesije može mnogo više da pogorša performanse servera. Čemu držati (potencijalno veliki) objekat u memoriji kad je konekcija sa korisnikom ionako zatvorena čim mu je poslat HTML kod za stranicu? Kada se slanje stranice završi, serveru (odnosno, GC-u) treba ostaviti slobodu da odradi svoj posao lepo, ako zatreba memorije.
U Session promenjivim se obično drži minimalan skup podataka: npr. dovoljno je da držiš int UserID koji dobiješ nakon što si verifikovao korisnika.
Svaki put kada ti zatrebaju podaci o korisniku na nekoj strani, jednostavno bi imao nešto poput:
Code:
int userID = System.Convert.ToInt32( Session["UserID"] );
CUser myUser = new CUser( userID );
this.labelImePrezime.Text = myUser.Fullname;
..
a tamo (u konstruktoru i drugim privatnim funkcijama) bi onda objekt izvršio povezivanje sa bazom, određeni upit i popunio svoje članove podatke. Ti podatke onda lepo čitaš preko svojstava i prikažeš na stranici kako ti već treba. Sad, ako objekt nije veliki, mogao bi da ga strpaš u Session, ali nije preporuka generalno. Čim su objekti kompleksiniji (npr. sadrže reference na druge objekte ili čak čitave kolekcije drugih objekata) znači da će i zauzeće memorije biti veće. Dobro, ne moraš u ovom slučaju da budeš toliko restriktivan i ograničiš se na samo UserID, možeš još neke podatke da ostaviš, ali treba imati mere - ne znam ni sam tačno šta bi bilo "mnogo".
Što se tiče podataka koji bi se prikazivali u DataGrid kontroli, možeš jednostavno napraviti public static funkcije koje će da vraćaju DataSet objekt. Ako je još potrebno i sortiranje, napravi to kao ulazni parametar funkcije. Npr.
Code:
DataSet podaci = CUser.GetUserSet( bool sortDescending ); // podaci o svim korisnicima
dataGrid1.DataSource = podaci;
dataGrid1.DataBind();
ili možeš čak da napraviš funkciju koja bi vraćala ArrayList CUser objekata, koji se takođe lepo prikazuju ud DataGridu (pošto ArrayList implementira IEnumerable), ali takva odluka je sad već vođena drugim stvarima (npr. klikom na link u tabeli, pozoveš odmah određenu funkciju tog CUser objekta ili šta već :).
I ovo pozivaš u recimo Form_Load svaki put (tj. verovatno NE kada je Page.IsPostBack == true).
Citat:
ali covek, koliko sam ja razumeo, pita za slucaj sortiranja i ponovnog prikazivanja strane, i za takvu stvar mislim da je bolje tabelu drzati u objektu DataView pa njega sortirati, nego ga ponovo uzimati iz baze...
Nije problem povezivati se sa bazom (connection pooling je tu), a baza ionako više voli da odrađuje neke upite nego da sedi i ne radi ništa po ceo dan :) Nikakvo toliko strašno usporenje neće se desiti zbog ovog - baza očas posla odradi upit, ne treba to toliko da brine (a ako se dešava, onda je verovatno vreme za generalku). Evo možemo da pitamo Gojka koliko upita ES vrši prosečno po jednoj stranici (dobro, ovde je broj značajno veći zbog toga što MySQL i ne podržava najbolje SQL92 pa mora da se vrši više jednostavnijih upita, ali opet - dođe na isto).
Ne treba zaboraviti da je slučaj različit od desktop aplikacije, gde će korisnik da verovatno ima jednu kopiju aplikacije pokrenutu, dok server mora da opslužuje n korisnika. U slučaju desktop aplikacije mi rasterećujemo server ako podatke držimo lokalno, a ovde bi ga opterećivali, više nego što ćemo da ga optrećujemo time što će za svako generisanje stranice morati da se ponovo spoji sa bazom. Nije to problem.
Svakako, za potrebe prikaza (sortirano ili ne) nema potrebe koristiti DataSet klasu, već DataReader, tako da onaj gore primer koji sam dao i nije najbolji.
I jedno i drugo ima prednosti i mana:
Citat:
This brought Dan (the DotNetMan) Green to the stage. Dan's from Monash.NET an Australian company specializing in training and consulting.
Datareader vs Datadapters:
The interesting subject of data readers vs data adapters and performance was then discussed. Here he said that it was horses for courses. Datareaders are really good for process that required a read once, like populating the business objects. He noted that datareaders follow the process of Connect, Retrieve, Process, Close and mentioned that if the processing of the data being read takes a long time then a datareader might not be suitable as resources on the database are held open until the processing is completed.
With DataAdapters the process is Connect, Retrieve, Close and Process. This means ithat the processing is done after the connection to the database is closed. Therefore, it is potentially more scalability. However, with any recommendation there was a note of caution in terms of size of data this is because dataset actually holds 2 copies of the data, the original data retrieved and the current state of the data.
Commercial-Free !!!