Poslao: 28 Feb 2007 09:08
|
offline
- IgorMedo
- Građanin
- Pridružio: 25 Mar 2006
- Poruke: 67
- Gde živiš: Doboj, Republika Srpska
|
Postovani,
Posto pravim jednu aplikaciju koristio sam TThread za upis i pisanje podataka u bazu. tj. sve sto radim u bayi radi preko toga. Osnovni raylog zasto sam se odlucio za to je sto sam citajuci u knjizi nasao racenicu slicunu sledecoj.
Kada koristite proces za vrsenje neke operacije a ne zelite da aplikacija bude zamrznuta dok se to desava koristite tthread i onda ja odlucim da napisem tthread za pristup bazi i sve operacije koje radim sa bazom odradim preko toga. I stvarno radi u pozadini a aplikacija radi normalno ali po zavrsenom procesu pada mi glavna aplikacija nisam koristio komandu synchronize ali kada nju koristim blokira mi glavna aplikacija pa onda imam utisak da sam sve djabe radio. Molim pomoc.
Dopuna: 28 Feb 2007 9:08
e ovako ovaj kod moram da pozovem sa metodom synchronize
procedure TProces.konektuj;
var
Ucitano:boolean;
begin
//showmessage('Konekcija!');
Ucitano:=False;
if Stanje<>0 then
MBPInc.Destroy;
MBPInc:=TMBPInc.Create(FGlavna);
with MBPInc do
begin
while not Ucitano do
begin
try
BPKonekcija.Connected:=True;
Application.ProcessMessages;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
Ucitano:=False;
while not Ucitano do
begin
try
FLoad.Label1.Caption:='Grupe!';
Application.ProcessMessages;
SQLUGrupe.Close;
//UGrupe.Prepare;
SQLUGrupe.Open;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
Ucitano:=False;
while not Ucitano do
begin
try
FLoad.Label1.Caption:='Marke!';
Application.ProcessMessages;
SQLUMarke.Close;
//UMarke.Prepare;
SQLUMarke.Open;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
Ucitano:=False;
while not Ucitano do
begin
try
FLoad.Label1.Caption:='Akcije!';
Application.ProcessMessages;
SQLUAkcije.Close;
//UAkcije.Prepare;
SQLUAkcije.Open;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
Ucitano:=False;
while not Ucitano do
begin
try
ZTMarke.Active:=True;
ZTGrupe.Active:=True;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
Ucitano:=False;
while not Ucitano do
begin
try
FLoad.Label1.Caption:='Uredjaji!';
Application.ProcessMessages;
SQLUUredjaji.Close;
//UUredjaji.Prepare;
SQLUUredjaji.ParamByName('Start').AsInteger:=Lista*15;
SQLUUredjaji.Open;
FGlavna.IPUredjaji.DataSet:=SQLUUredjaji;
FGlavna.BPSlika.DataSource:=FGlavna.IPUredjaji;
FGlavna.BPSlika.DataField:='Slika';
FGlavna.IPAkcije.DataSet:=SQLUAkcije;
FGlavna.BPSlikaA.DataSource:=FGlavna.IPAkcije;
FGlavna.BPSlikaA.DataField:='Slika';
//SQLULUredjaja.Close;
//SQLULUredjaja.Open;
Ucitano:=True;
except
Ucitano:=False;
end;
end;
end;
end;
a za ostatak koda u unitu nisam koristio metod synchronize
|
|
|
Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
|
|
Poslao: 28 Feb 2007 10:33
|
offline
- bobby
- Administrator
- Pridružio: 04 Sep 2003
- Poruke: 24135
- Gde živiš: Wien
|
Za pocetak izbaci application.processmessages iz threada, to je visak sigurno.
Jesi li sigurno instancirao thread? Da nisi kojim slucajem radio nad samom klasom bez instanciranja?
|
|
|
|
Poslao: 28 Feb 2007 10:38
|
offline
- IgorMedo
- Građanin
- Pridružio: 25 Mar 2006
- Poruke: 67
- Gde živiš: Doboj, Republika Srpska
|
application.processmessage sam naknadno ubacio posto mi je aplikacija nije nastavljala sa radom.
a evo kod koji poziva thread
Sat.Enabled:=False;
Zavrseno:=False;
Proces:=TProces.Create(True);
Proces.Lista:=Lista;
Proces.Stanje:=Stanje;
Proces.FreeOnTerminate:=True;
Proces.Resume;
while not Zavrseno do
begin
Application.ProcessMessages;
end;
Proces.Terminate;
close;
a evo metod execute od procesa
procedure TProces.Execute;
begin
if (Stanje=0) or (Stanje=1) then
synchronize(konektuj)
//konektuj
else if Stanje=2 then
//synchronize(rekonektuj)
rekonektuj
else if (Stanje=3)or(Stanje=4) then
//synchronize(snimi)
snimi
else if (Stanje=5)or(Stanje=6) then
//synchronize(otvoriu)
otvoriu
else if (Stanje=7)or(Stanje=8) then
//synchronize(OtvoriA)
OtvoriA
else if (Stanje=9)or(Stanje=10) then
//synchronize(SnimiA);
SnimiA;
FLoad.Zavrseno:=True;
end;
samo prvi metod ne mogu da pozovem bez synchronize ostale mogu a njegov kod sam vec napisao.
|
|
|
|
Poslao: 28 Feb 2007 12:12
|
offline
- beli0135
- Executor
- Pridružio: 03 Jan 2005
- Poruke: 2990
- Gde živiš: Beograd
|
@IgorMedo
Gledajuci tvoj code, vidim da nisi bas 'ortak' sa Threadovima.
Rad sa bazama pod threadom zahteva mnogo vise znanja.
Moj ti je savet da sve to prebacis na bez upotrebe threadova (single thread aplikacija), a da sa threadovima vezbas tako sto ces napraviti programce koji ce da promeni dimenzije slike, i to 4-5 odjednom.
E kad to savladas, i savladas rad sa bazama, tek onda idi na thread.
Druga stvar je da se thread na bazama ne koristi tako kako ga ti koristis.
Prvo moras da imas kompletan objekat koji nezavisno radi sa bazama. Nezavisno, u smislu da ne zavisi ni od ceg, osim od parametara za konekciju, recimo, TDatabase komponente.
Onda moras da imas thread-pool koji ce izvrshavati kompletne objekte.. ali to je vec za 3-tier baze. Za bilo sta sto nije RDBMS -> Application Server -> Thin client ZABORAVI.
|
|
|
|
Poslao: 28 Feb 2007 12:26
|
offline
- IgorMedo
- Građanin
- Pridružio: 25 Mar 2006
- Poruke: 67
- Gde živiš: Doboj, Republika Srpska
|
Sve to lijepo zvuci, ali kako da naucim da radim sa threadovima kada u bilo kojoj literaturi koju imam o threadovima dvije stranice.
A sad mi objasni znacenje ove redenice:
Prvo moras da imas kompletan objekat koji nezavisno radi sa bazama.
Hvala
|
|
|
|
Poslao: 28 Feb 2007 13:05
|
offline
- beli0135
- Executor
- Pridružio: 03 Jan 2005
- Poruke: 2990
- Gde živiš: Beograd
|
Au, to je problematicno, izgleda ...
TMojaBaznaKlasaZaRadSaBazom = class(TObject)
private
...
protected
...
public
....
end;
TMojaKlasaZaCitanjePodataka = class (TMojaBaznaKlasaZaRadSaBazom)
....
....
TMojaKlasaZaManipulacijuPodataka = class (TMojaKlasaZaCitanjePodataka)
...
I ides redom...
Implementiras metode u prvu koji sluze ka konekciju, kreiranje upita itd, pa nadogradjujes klasom koja ce imati sve sto jedna Read-Only klasa treba da ima, pa onda nadogradjujes sa klasom koja moze da radi insert, update i delete...
Jbg.. ne znam sta da ti kazem.. dosta posla tu ima. Ne mogu ni da ti dam primer ovde, sve je to po pola kilometra koda.
|
|
|
|
Poslao: 28 Feb 2007 13:32
|
offline
- IgorMedo
- Građanin
- Pridružio: 25 Mar 2006
- Poruke: 67
- Gde živiš: Doboj, Republika Srpska
|
Hval na pojasnjenju
Nesto slicno tom radim kada pravim pravu aplikaciju ali kada pravim nesto na brzinu koristim upite i gotove komponente nemam potreb za tim, pravim aplikaciju koja upisuje sadrzaj na stranicu pami se nepise puno koda.
Ali sa threadovima radim prvi put imali negdje literatutre.
|
|
|
|
Poslao: 28 Feb 2007 13:56
|
offline
- bobby
- Administrator
- Pridružio: 04 Sep 2003
- Poruke: 24135
- Gde živiš: Wien
|
Princip kreiranja threada si definitivno skontao.
Ima tu jos par principa koje ja postujem (isto sam rad sa threadovima ucio sam).
Prvo, u threadu koristim lokalne varijable ili klase, ne pristupam direktno onim varijablama i klasama iz glavnog threada.
Recimo, u threadu treba da koristis neki tekst koji ti se na formi nalazi u Memo komponenti. Ne pozivas iz threada citanje teksta Memo komponente vec u instanci threada napravis string varijablu i metodu za njeno punjenje (Set metodu).
Kada kreiras thread kreiras ga u suspended stanju, pa onda iz glavnog threada preko metode Set koju imas u threadu uneses ono sto imas u Memo.text, pa onda odradis resume thread kada si tako preneo sve potrebne parametre. Beli ti je gore objasnio na primeru klasa, ja na primeru varijabli. Sve u svemu, thread treba u samom sebi da moze da inicijalizuje sve ono sto mu treba za rad, pa mu pri kreiranju iskoristis suspended flag, iskopiras podatke iz instanci klasa koje imas u glavnom threadu u instance koje imas u klasi, pa onda uradis resume threada. Na kraju odradjenog posla odradis synchronize u kojem iskopiras podatke iz lokalnih instanci u one u glavnom threadu. Puno posla, ali samo tako thread moze da radi nezavisno dovoljno dugo da ti glavni thread moze raditi nesto drugo.
Drugo, ti imas previse poziva za sinhronizaciju, tako da iako si napravio thread ti i dalje drzis glavni thread "pod pritiskom", pa u glavnom threadu ipak dolazi do zamrzavanja osvezavanja forme.
Projektuj thread tako da nema puno synchronize poziva. U toku rada threada koristi synchronize samo u vidu nekog progress eventa, a tek na kraju mu odradi synchronize koji ce da prenese podatke/rezultate glavnom threadu.
|
|
|
|
|
Poslao: 28 Feb 2007 17:14
|
offline
- beli0135
- Executor
- Pridružio: 03 Jan 2005
- Poruke: 2990
- Gde živiš: Beograd
|
@Bobby, secamo li se "onog" problema? ehehe
Elem, sve je to normalno. Tako se uci nema druge.
Osnovne greske su koriscenje globalnih varijabli, previse oslanjanja na drugi (ili main) thread, direktno prenosenje promenjivih, zvanje threada sa vise mesta itd.
To mora da se prodje.
Medjutim, najveca greska je koriscenje threadova tamo gde nema potrebe za njima. Tu 90% ljudi gresi. Treba obratiti paznju na to da li uopste thread ima smisla za dati problem.
|
|
|
|