Newsgroup: it.comp.lang.delphi
Titolo: TThread e Synchronize()

Ho un problema con quanto in oggetto.
Ho un'applicazione composta da due units, la prima con il thread principale 
ed un thread secondario, la seconda contempla solo una classe TThread.
Questo thread si occupa di creare dei valori random e accompagno le 
operazioni  aggiornando tre TProgressBar e delle TLabel.
Ora, dalle info reperite in rete, si suggerisce di utilizzare il metodo 
Synchronize() per intervenire su queste in tale modo
procedure MyThread.AggiornaPB;
begin
  form1.progressbar1.stepit;
end;
oppure
procedure MyThread.AggiornaLBL;
begin
  form1.label1.caption := 'nuovacaption';
end;
e dall'interno del thread richiamarle con Synchronize().
Succede che se utilizzo tale metodo l'applicazione non risponde 
correttamente, i TButton che utilizzo per avviare e sospendere  il thread 
dovrebbero abilitarsi e disabilitarsi secondo l'operazione in corso ma si 
manifestano dei rallentamenti.
Se al contrario non "sincronizzo" tutto sembra procedere bene.
La ragione appare chiara, proprio causa la peculiarità di Synchronize(), ma 
in questo stesso ng si era detto di non utilizzare delle chiamate dirette 
dal thread ai componenti VCL.
Cosa ne pensate?
Valter
 

 Synchronize() per intervenire su queste in tale modo
Infatti la VCL non è thread-safe, la gestione degli oggetti VCL deve
essere eseguita dal thread principale o comunque sincronizzata.  In ogni
caso, quando hai più thread, meno corse critiche hai, meglio è; se puoi
evitare accessi concorrenziali a risorse, che vanno necessariamente
sincronizzati, fallo.
Il metodo che ti suggerisco è di sfruttare il più possibile le code di
messaggi di sistema e quindi usare GetMessage/PeekMessage per reperire i
messaggi dalla coda e PostThreadMessage per inserirli nella coda di un
thread.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 thread.
ed infatti, sostituiti i Synchronize() dei TProgressBar con i 
PostThreadMessage, problema risolto.
Ora si tratta solo di definire i metodi migliori e meno invasivi da 
utilizzare per gli altri passaggi.
Grazie
Valter

 avanzamento mi vedo costretto a mettercela
Non sto dicendo di non mettere ciò che ti serve, ma di accedervi con una
modalità alternativa alla sincronizzazione esplicita.


 utilizzare per gli altri passaggi.
Scusa ma non ho capito perche' va' usato PostThreadMessage invece di un 
normale PostMessage. Non devi sincronizzarti col thread principale per il 
tprogressbas?
Giorgio 

 normale PostMessage.
PostThreadMessage() è la funzione che si utilizza, normalmente, per
mandare messaggi tra thread, facendo a meno di specificare un handle di
finestra.  PostMessage(), invece, ha come destinatario una finestra
specifica.
Come tecnica generale per comunicare tra thread, è bene usare
PostThreadMessage(), se si ha invece una finestra in particolare a cui si
vuol mandare messaggi, allora si usi PostMessage().


 ha scritto nel messaggio 
news:4597a1ed$0$7748$5fc...@news.tiscali.it...

Ho però constatato che, se proprio dovesse occorrere sincronizzare le 
operazioni, posponendo Application.ProcessMessage ad ogni chiamata 
Synchronize() tutti i controlli rispondono immediatamente. Probabilmente va 
a scapito delle performance ma ho successivamente verificato che il problema 
me lo dava solo sulle chiamate StepIt dei tre TProgressBar che chiamo due 
volte per ogni ciclo. Non ho riscontrato differenze di prestazioni.
V

 vuol mandare messaggi, allora si usi PostMessage().
Questo e' chiaro, ma mi chiedo Delphi gestisce una coda di messaggi di tal 
tipo o devi implementarla tu.
Giorgio

 ha scritto nel messaggio 
news:RI8mh.12751$AA.1...@tornado.fastwebnet.it...

se non deve essere super veloce, nel ciclo del thread metterei un 
sleep(100), che da "respiro" al thread principale.
Ciao Giorgio 

 tipo o devi implementarla tu.
Delphi ti lascia interfacciare l'API di Windows e quindi usufruire delle
code di messaggi di sistema.  Non c'è niente da implementare a mano se non
l'immissione (PostMessage/PostThreadMessage) e il prelevamento
(GetMessage/PeekMessage) dei messaggi (ovviamente).
Non so se ho chiarito il tuo dubbio.


 sleep(100), che da "respiro" al thread principale.
Il thread principale non ha bisogno di respiro, se affida le elaborazioni
a un worker thread.  Non ha molto senso usare degli Sleep() ed io lo
sconsiglio sempre. Un thread deve lavorare e consumare CPU e può farlo
benissimo in "apnea". Anche perché non si capisce bene su quale base di
stima il tempo da passare alla Sleep().


 Non so se ho chiarito il tuo dubbio.
No. Se uso il PostMessage, diretto ad esempio alla form, e' sufficciente 
definire un messaggio custom ed usare il suo evento per gestire i Msg 
inviati dal thread.
Se come dite uso il PostThreadmessage non mi e' chiaro in quale evento 
(tramite la getmessage) vado a prelevare il messagio del thread secondario.
Giorgio

 (tramite la getmessage) vado a prelevare il messagio del thread secondario.
Non hai seguito bene quello che scrivevo: se dirigi i tuoi messaggi, nello
specifico, a una *finestra*, allora usi PostMessage().  Se dirigi i tuoi
messaggi a un thread (e quindi li preleverai con
GetMessage()/PeekMessage() nell'Execute) userai PostThreadMessage().
Per comunicare *tra thread*, va bene PostThreadMessage.


 stima il tempo da passare alla Sleep().
Non sono d'accordo, ho avuto modo di verificare un miglioramento delle 
"interruzioni" del thread principale a causa dei syncronize inserendo lo 
sleep.
In base a quali considerazioni assegnare il tempo? lo assegni in funzione 
della cadenza che puo' supportare il thread.
Giorgio 

 della cadenza che puo' supportare il thread.
Da parte mia ho perň constatato che in certi casi lo sleep() rischia di 
essere inadeguato...a secondo dell'uso che se ne fa puň capitare che la 
stessa applicazione risponda correttamente una certa volta e meno bene 
un'altra...nel caso della TProgressBar richiamata con cadenza frequente da 
un Synchronize() ho preferito utilizzare Application.ProcessMessage
Valter
 

 Valter
Nel tuo caso specifico avrei usato un Postmessage con un messaggio custom, 
potendo mettere poi nel suo gestore quello che ritieni ,
Ciao Giorgio 

sleep.
Gli sleep() non servono a migliorare alcunché.

Segnalo solo un doc se non conosciuto che dovrebbe chiarire meglio le idee
sulle sincronizzazioni.
Ciao
ID:  17644
Thread Manager (for Delphi 7 and Kylix 3)
by Guinther Pauli Email: 
guin...@devmedia.com.br
Create threads and synchronize them using Mutexes, Critical Sections or
Semaphores, and terminate (kill), suspend, resume, change priority, create
suspended threads.
http://cc.codegear.com/Item.aspx?id=17644
Credo si debba iscriversi per scaricare il doc, eventualmente dal caro mulo.
--- posted by geoForum on 
http://www.delphiedintorni.it


http://cc.codegear.com/Item.aspx?id=17644
Facilissimo iscriversi, poi per una DEMO guarda anche
http://cc.codegear.com/Item.aspx?id=24298
