[ franjo_tahi2 @ 12.06.2014. 14:20 ] @
| Imam cca 15 qry-a koje se otvaraja na početku programa i zahvačaju sve podatke (morat tako, ne pitajte zašto...)
Koristim TIBDataSet, u stvaru kontrol koja ne napravljena na TIBDataSet (dodati neki parakmetri, dodana interna transakcija, mogućnost select, orerder, join dijelova...)
Svi qry-i su mi na datamodulu, na njih su zakačene datastt-ovi i na ove grid-ovi
Pokušao sam napraviti otvaranje u zasebnim thread-ovima, ali ne prolazi...
Code:
tm=class(TThread)
private
fq: TIBDataSetNew;
protected
procedure Execute; override;
public
constructor Create(qry: TIBDataSetNew);
end;
constructor tm.Create(qry: TIBDataSetNew);
begin
fq := qry;
inherited Create(true);
Resume;
end;
procedure tm.Execute;
begin
if (fq <> nil) and not(fq.Active) then begin
fq.Open;
end;
end;
i u main formi gumb:
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
if not ibd.Connected then ibd.Open;
tm.Create(q1);
tm.Create(q2);
end;
Što ne valja? Ponekad otvori oba qry-a, ponekad u jedno prikaže samo 1 field od njih 20-tak, poneka otvori samo jedan qry....
|
[ reiser @ 12.06.2014. 18:09 ] @
Ne mozes tek tako da prosledjujes pointere ka query objectima u thread, umesto toga napravi lokalni query objekat unutar threada, izvrsi query, i iz threada vrati rezultat glavnom threadu preko synchronize() ili PostMessage().
(mozda nisam u pravu jer vrlo slabo radim sa bazama, ali prosledjivanje VCL objekta threadu definitivno smrdi)
[ franjo_tahi2 @ 13.06.2014. 07:47 ] @
Iz onoga što sam čitao, i meni to nije baš ok, ali ne znam kako drugačije i da li uopće može to što sam zamislio.
Ne mogu kreirati novi qry u thread-u jer se na onaj koji mu prosljeđujem iz glavnog thread-a naslanjaju grid-ovi i još ponešto, a i koristim njegove AfterOpen, AfterScroll itd event-e
[ franjo_tahi2 @ 13.06.2014. 09:46 ] @
Mislim da sam našao rješenje. Ako mislite da nije uredu, molim savjet.
u thread sam dodao proceduru Open u koju sam prebacio otvaranje qry-a iz procedure Execute, a u proc Execute pozivam proceduru Open:
Code:
...
private
procedure Open;
...
end;
procedure tm.Open;
begin
if (fq <> nil) and not(fq.Active) then begin
fq.Open;
end;
end;
procedure tm.Execute;
begin
Synchronize(Open);
end;
Idem to uglaviti u program pa da vidim razilku. Na testu s 2 tablice rezulat:
Open preko threada: 4-7 ms
Direktan open u formi: 65-75 ms
[ reiser @ 13.06.2014. 12:39 ] @
Citat:
Ne mogu kreirati novi qry u thread-u jer se na onaj koji mu prosljeđujem iz glavnog thread-a naslanjaju grid-ovi i još ponešto, a i koristim njegove AfterOpen, AfterScroll itd event-e
Onda je upravo to problem, mesas VCL u threadovima, a VCL nije thread-safe. A ovaj zadnji primer koji si naveo ne radi nista drugo nego izvrsava Open() u glavnom threadu, isti ces efekat dobiti i ako stavis fq.Open() u data modulu.
http://stackoverflow.com/quest...the-query-how-to-prevent-freez
[ savkic @ 14.06.2014. 19:14 ] @
Uvek kada radiš sa threadovima a posebno sa bazom i threadovima moraš voditi računa o više stvari, npr:
- nikada ne mešati i koristiti jedan resurs u više threadova, istovremeno, osim ako to nije eksplicitno dozvoljeno (npr, string je threadsafe)
- nikada ne pozivati resurs koji je u jednom threadu iz drugog, dakle da iz glavnog threada pozoveš neki dataset iz pomoćnog i da koristiš njegov resultset.
Natrag na tvoj problem
> Imam cca 15 qry-a koje se otvaraja na početku programa i zahvačaju sve podatke (morat tako, ne pitajte zašto...)
> Koristim TIBDataSet, u stvaru kontrol koja ne napravljena na TIBDataSet (dodati neki parakmetri, dodana interna transakcija, mogućnost select,
> orerder, join dijelova...)
> Svi qry-i su mi na datamodulu, na njih su zakačene datastt-ovi i na ove grid-ovi
> Pokušao sam napraviti otvaranje u zasebnim thread-ovima, ali ne prolazi...
To ne može tako, nekoliko stvari, moraš videti da li je uopšte IBX thradsafe (koliko se sećam, nije), ako nije onda za svaki objekat (dataset) u posebnom threadu moraš imati posebnu DB konekciju ovako ti ako staviš datasetove u poseban thread oni svi koriste isti main thread db connection objekat. Drugo nikako nemoj da to radiš dok je dataset zakačen na db aware kontrole.
Kao opšte pravilo (ima i izuzetaka) threadovi se kod pristupa bazi koriste da ubrzaju neke operacije, tipa generisanje izveštaja, kalkulacije i slično što zahteva dosta vremena. Ali se nekoriste za ubrzavanje pregleda podataka. Ako imaš problem sa sporim prikazom podataka onda gledaj da optimizuješ svoje kverije, da ih filtriraš i slično.
[Ovu poruku je menjao savkic dana 14.06.2014. u 20:31 GMT+1]
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.