Newsgroup: it.comp.lang.delphi
Titolo: Thread sui Thread - Datemi speranza

Ho bisogno di chiarire la mia filosofia sull'uso dei thread in Delphi.
Utilizzo Delphi 7.0 e ho Windows XP Pro.
1 Gb Ram e un computer nuovo di zecca.
Tuttavia nel corso del mio sviluppo sbatto la testa (dolorosamente) 
contro l'utilizzo dei thread.
Voglio dire, l'idea è ottima: moltiplicare il lavoro della CPU in 
attività distinte e -apparentemente- contemporanee.
Purtroppo la MIA realtà è ben diversa.
Devo utilizzare 6 thread per attività contemporanee di esecuzione query 
su uno stesso DB.
Adotto tutte le attenzioni del caso, dopo aver studiato esempi di 
persone più esperte di me:
- utilizzo di sessioni distinte per le query, nominate univocamente;
- FreeOnTerminate := True;
- utilizzo di variabili locali per costruire un'unica chiamata agli 
oggetti non thread-safe;
- accesso a tali oggetti con Synchronize(procedura);
- attenzione alla chiusura dei thread durante la loro attività, con 
ripetuti controlli "if NOT Terminated then";
- lungaggini enormi derivate dal controllo di procedure che altrimenti 
sarebbero estremamente semplici ma che, fatte così, diventano più 
impegnative del programma stesso.....
Risultato:
mi trovo a dover fare i conti con errori diversi, le cui cause sono 
sempre difficilissime da trovare, e che mi fanno arrivare al punto di 
odiare i thread e desiderare terribilmente di eliminarli tutti...
... MA NON LO VOGLIO FARE!!! Sarebbero troppo comodi se funzionassero.
Qualcuno può rinvigorire la mia fiducia nei thread e dirmi:
"SI' FUNZIONANO! NON TI PREOCCUPARE, VA TUTTO BENE.. I THREAD 
FUNZIONANO." Sarebbe bellissimo. Così come sarebbe bello capirne un po' 
di più per farli funzionare.
Esempi di codice:
-------------------------------------
procedure TfrmMain.FaiPartireThread;
begin
if Assigned(MyThread)
AND (NOT MyThread.Terminated) then
     begin
     MyThread.Terminate;
     MyThread.WaitFor;
     end;
CheckUpThread := MyThread.Create;
end;
constructor MyThread.Create;
begin
fDatabaseName := MyDBCartella;
fSession := TSession.Create(nil);
fSession.SessionName := Self.ClassName+IntToStr(Random(100000));
fPersona := UnitMain.IDPersonaCheVoglio;
FreeOnTerminate := True;
inherited Create(False);
end;
procedure MyThread.Execute;
var MyQuery : TQuery;
begin
try
     try
         if NOT Terminated then
             begin
             fKey := 'TABELLA VISITE';
             fValue := '';
             Synchronize(Update);    //PROCEDURA DI SCRITTURA RISULTATI
             MyQuery := TQuery.Create(nil);
             with MyQuery do
                 begin
                 SessionName := fSession.SessionName;
                 DatabaseName := fDatabaseName;
                 SQL.Add('SELECT Nome');
                 SQL.Add('FROM "tblNomi.DB" tblNomi');
                 SQL.Add('WHERE (IDPersona = :IDPersona)');
                 SQL.Add('ORDER BY Nome ASC DESC');
                 Params[0].AsInteger := fPersona;
                 Open;
                 fKey := 'N.Record';
                 if IsEmpty then
                     fValue := '0'
                 else
                     fValue := inttostr(RecordCount);
                 Synchronize(Update); //PROCEDURA DI SCRITTURA RISULTATI
                 if not IsEmpty then
                     begin
                     fKey := 'Ultima persona';
                     fValue := MyQuery.FieldByName('Data').AsString;
                     Synchronize(Update); //SOLITA PROCEDURA
                     end;
                 Close;
                 Free;
                 end;
             end;
     except
         on E:Exception do
             begin
             fStatus := E.Message;
             Synchronize(Status);  //PROCEDURA DI SEGNALAZIONE ERRORE
             Terminate;
             Abort;
             end;
     end
finally
     Synchronize(ShowText);  //PROCEDURA DI FINE LAVORO
     MyQuery.Free;
     fSession.Free;
end;
end;
-------------------------------------
Esempi di errore:
"Access violation at address 00000000. Read of address 00000000."
oppure
La finestra principale del programma non si visualizza mai perché 
nell'esecuzione precedente i thread hanno fatto qualche guaio e devo
interrompere il processo con il Task Manager.
... e altre assurdità.
-------------------------------------
Grazie per aver letto fin qui.
Un saluto al newsgroup.

 interrompere il processo con il Task Manager.
L'Access Violation può essere dovuto a migliaia di ragioni, ma
presumibilmente al fatto che la connessione usata dal BDE per l'accesso ai
dati è unica, devi usare TDatabase diversi per ogni thread, ma nulla
garantisce che funzioni.  Sei sicuro di non poter cambiare tecnologia DB ?
Io ho usato dbExpress in contesti multi-thread e non ho mai avuto problemi.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it