Newsgroup: it.comp.lang.delphi
Titolo: Thred  perchè non fuonzioni?

Ciao a tutti,
All'interno di un' applicazione devo eseguire una funzione di calcolo che
dura diverso tempo (2/3 minuti). Visto che questa funzione non ha bisogno
di interfaccia grafica, ho pensato di crearmi una form di attesa con una
progressbar mentre viene eseguito il calcolo.
Per lanciare la form di attesa ho pensato di inserirla in un thread, per
cui vorrei lanciare il tread che visualizza la form e poi lancio il
calcolo.
Fin qui tutto ok, il problema � che una volta lanciato il thead la form
non si aggiorna mai per cui la progressbar rimane sempre a 0.
Ppoi una volta terminato il calcolo il thread riparte... 
Perch�? 
Dove sbaglio?
Suggerimenti?
Questo � il mio thread:
TDialogThrd = Class(TThread)
  private
    Form : TFrmDialogForm;
    FMin : Integer;
    FMax : Integer;
    FPos : Integer;
  protected
    procedure Execute; override;
    procedure UpdateProgress;
  public
    constructor Create(Param : TDialogParam);
end;
constructor TDialogThrd.Create(Param: TDialogParam);
begin
  inherited Create(True);
  //
  FMin := Param.Min;
  FMax := Param.Max;
  FPos := 0;
  //
  Form := TFrmDialogForm.Create(nil);
  Form.PTitolo   := Param.Titolo;
  Form.PTesto    := Param.Testo;
  Form.PBtnTit   := Param.BtnTit;
  Form.PMin      := Param.Min;
  Form.PMax      := Param.Max;
  //
  Form.Show;
  //
end;
procedure TDialogThrd.Execute;
begin
  while FMax > FMin do begin
    Synchronize(UpdateProgress);
    inc(FMin);
    //sleep(1000);
  end;
  Synchronize(UpdateProgress);
end;
procedure TDialogThrd.UpdateProgress;
begin
  Form.pBar.Position := FMin;
end;
Eseguo il Thread
procedure TForm1.Calcola;
var
  Thr : TDialogThrd;
  Par : TMXDialogParam;
begin
  //
  Par.Titolo   := 'Calcolo';
  Par.Testo    := 'Esecuzione Calcolo';
  Par.BtnTit   := 'Annulla';
  Par.Min      := 1;
  Par.Max      := 300;
  //
  Thr := TMxDialogThrd.Create(aParam);
  Thr.Resume;
  //
  // Esegui calcolo ........
  //
end;
Grazie
Ciao
Loris
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 non si aggiorna mai per cui la progressbar rimane sempre a 0.
Nel metodo di updateprogress ti manca un: Application.ProcessMessages;
Non ho provato, ma così dovrebbe funzionare:
procedure TDialogThrd.UpdateProgress;
begin
   Form.pBar.Position := FMin;
   Form.Repaint;
   Application.ProcessMessages;
end;
Forse il Repaint non è neanche necessario. Prova.
Gp
--
GP engineering and software
in...@gpsoftware.it
http://www.gpsoftware.it/

 non si aggiorna mai per cui la progressbar rimane sempre a 0.
Devi dire alla GUI di aggiornarsi. Non ho provato, ma dovrebbe
funzionare questa semplice modifica al metodo UpdateProgress:
procedure TDialogThrd.UpdateProgress;
begin
  Form.pBar.Position := FMin;
  Self.Repaint;
  Application.ProcessMessages;
end;
Ciao,


 
http://www.gpsoftware.it/
-- 


> Per lanciare la form di attesa ho pensato di inserirla in un thread,
sbagliato.
Nel thread devfinisci una property con la quale assegni una callaback:
Type
  TMyCallback = procedure(sender: TOBject; const AMax, ACurrent:
integer; var AStopped: boolean) of object;
  TMyThread = class(TThread)
  ...
  public
     property OnCallBack: TMyCallback read FOnCallback write
FOnCallBack;
  end;
A.

 progressbar mentre viene eseguito il calcolo.
[cut all]
C'è una certa contraddizione in quel che scrivi: se la funzione non ha
bisogno di un'interfaccia grafica, perchè fornirgliene una?
Da quel che leggo, esegui la funzione nel thread principale
dell'applicazione (quello normalmente destinato alla gui) e fai vedere
la progress bar in una form creata in un altro thread.
Ma Synchronize "Executes a method call within the main VCL thread".
Dato che il main vcl thread è impegnato nel calcolo, non può eseguire
anche updateProgress.
Dovresti invertire l'approccio: esegui la funzione in un thread e, se
proprio devi, ogni tanto posta un messaggio al thread principale
dicendo dove è arrivata la funzione.
Se invece ti serve solo che l'utente aspetti, usa la clessidra oppure
una dlgbox con pbar MA nel main vcl thread.
Saluti
Paolo Arosio

 sbagliato.



Grazie.
Ma poi la CallBack quando la devo richiamare?


 Grazie, ma avevo già provato e non cambia nulla....
Mi pare strano.
Quindi ti faccio una domanda: perché lanci un thread?
Io il thread lo uso per eseguire un processo in background mentre
l'utente fa dell'altro.
Se l'unico scopo è aggiornare una progress bar che si trova sul tuo
form gestisci un evento Onclick normalissimo.
Di seguito un esempio su una mia form sulla quale c'e':
- un button "crea bolle"
- una progress bar che faccio avanzare durante la creazione
- una label dove scrivo 'Creazione bolla nr. N'
L'utente non può fare nient'altro se non attendere, ma almeno vede
l'animazione. Nota anche il cambio dell'icona del mouse che passa a
clessidra all'inizio dell'operazione e poi torna standard alla fine.
Il metodo ovviamente l'ho semplificato.
procedure TfrmProduzione.btnBolleClick(Sender: TObject);
{ Genera tutte le bolle relative alla produzione proposta (bolle dei
clienti) }
begin
  // aggiorna la proposta di produzione
  numClienti := UpdatePropostaProduzione(lvClientiAperti.Items);
  Self.Invalidate;
  StartWait;
  try
    for i := 0 to numClienti do begin
	aItem := lvClientiAperti.Items.Item[i];
	. . .
	progressBar.Position := Round( 100.0 * i / numClienti);
	progressLbl.Caption := Format('Creazione bolla: %d%%',
[progressBar.Position]);
	Self.Repaint;
	Application.ProcessMessages;
    end;  // for...
  finally
    StopWait;
  end;
end;

> Ma poi la CallBack quando la devo richiamare?
Scusa, che domanda e'?
Nel tuo thread adesso come fai?
A.

 dura diverso tempo (2/3 minuti).
Sarebbe carino sapere poi che soluzione hai usato.
Ciao,
Gp

Gianpiero Caretti ha scritto:



Purtroppo al momento ( causa mancanza d itempo!)ho dovuto glissare...ho
tolto tutto e cambiato lo stato del Mouse.
Ma dai suggerimenti che mi sono arrivati, il mio approccio � sbagliato,
devo lanciare la form dal thread princiapale e con un theard secondario
eseguire il comando di calcolo...
