[ 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]