Newsgroup: it.comp.lang.delphi
Titolo: Progress Bar e chiamata a web service

Ho un metodo che chiama un web service e mi restituisce una stringa
importo = importoRequest();
Nel caso di lentezza nella connessione o del Web Service, questo
impiegherebbe un po per restituirmi il mio risultato.
Vorrei avere una form con il messaggio attesa e una progressbar o un
componente TJvWaitingGradient.
Il mio problema è che se web service lento --> mi blocco
sull'istruzione importo = importoRequest(); --> il componente
TJvWaitingGradient si blocca e allo stesso modo la progressbar !
Come posso fare ?
Grazie

 Come posso fare ?
Esegui l'importazione nell'execute di un TThread.
Saluti
Paolo Arosio

Ciao Paolo, grazie della dritta.
Non ho mai usato un TThread; ho fatto così ... questa è la form di
attesa dove vorrei avere una progress bar in movimento
La progress bar si sposta in posizione 80, ma non riesco ad usare un
componente JvWaitingGradient (una barra che continua a muoversi a
destra e a sinistra) !
unit UAttendere;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls, JvExControls, JvWaitingGradient, ComCtrls;
type
  TAttendere = class(TForm)
    Label1: TLabel;
    ProgressBar1: TProgressBar;
    JvWaitingGradient1: TJvWaitingGradient;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FThread:TThread;
  public
    { Public declarations }
  end;
TMyThread=class(TThread)
  private
    FTimeToWork : integer;
  protected
    procedure Execute;override;
  public
    constructor Create();
end;
var
  Attendere: TAttendere;
implementation
{$R *.dfm}
constructor TMyThread.Create();
begin
  //FTimeToWork := TimeToWork;
  inherited Create(True);
end;
procedure TMyThread.Execute;
begin
  while not Terminated do
    begin
       Attendere.ProgressBar1.position := 80;
    end;
end;
procedure TAttendere.FormCreate(Sender: TObject);
begin
  FThread:=TMyThread.Create();
  FThread.Resume;
end;
end.

 Non ho mai usato un TThread; ho fatto così ...
the other way round. L'attesa (progress bar, etc) la fai nel contesto
del thread principale. Il lavoro nel thread secondario. Quando il
lavoro è finito (OnTerminate) puoi sbarazzarti di progress bar etc. e
infine anche del thread.
Qualcosa tipo:
WM_THREADDONE = WM_USER +1;
procedure TmainForm.DoSomethingLong();
begin
  // spawn a thread do do lenghty processing
  if not assigned(fWorkThread) then begin
     fWorkThread := TmyWorkerThread.Create(true);
     fWorkThread.OnTerminate := ThreadDone;
     fWorkThread.Resume;
     showWaitPleaseForm();
  end
  else
    raise Exception.Create('Sono già al lavoro, schiavista!');
end;
procedure TmainForm.ThreadDone(Sender: TObject);
begin
  // get rid of WaitPleaseForm:
  waitPleaseForm.close;
  // see worker's results
  if fWorkThread.success then ...
  else ...
  // free and nil thread instance:
  // must be done outside of this method
  PostMessage(Application.MainForm.Handle,
    WM_THREADDONE, 0, 0);
end;
// chiamata (asincrona) alla conclusione dell'evento OnTerminate:
// deve eliminare il thread
procedure TMainForm.WMThreadDone(var Message: TMessage);
begin
  if Assigned(fWorkerThread) then
    FreeAndNil (fWorkerThread);
end;
Saluti
Paolo Arosio

Allora ho fatto così
TmyWorkerThread=class(TThread)
  private
    FTimeToWork : integer;
  protected
    Procedure Execute; override;
procedure TPay.SBConfermaClick(Sender: TObject);
begin
 if not assigned(fWorkThread) then
        begin
          fWorkThread := TmyWorkerThread.Create(true);
          fWorkThread.OnTerminate := ThreadDone;
          fWorkThread.Resume; // inizio esecuzione thread
          //showWaitPleaseForm();
          Application.CreateForm(TAttendere, Attendere);
          Attendere.Show;
        end
      else
        raise Exception.Create('Sono già al lavoro, schiavista!');
end;
procedure TPay.ThreadDone(Sender: TObject);
begin
  // get rid of WaitPleaseForm:
  attendere.close;
end;
procedure TmyWorkerThread.Execute;
var
  pagamentoResponseAsString : String;
begin
  pagamentoResponseAsString := pagamentoRequest(); //chiamata al ws
end;
E' la strada giusta ? Ora mi da errore su pagamentoRequest che è una
funzione di TPay ....
La procedura WMThreadDone la chiamo dopo il metodo
pagamentoRequest() ?

 pagamentoRequest() ?
La procedura è un message handler, non la chiami direttamente ma con
un PostMessage, in modo da eseguirla in asincrono rispetto alla fine
dell'esecuzione del thread. Questo solo per consentire di "esaminare"
lo stato del thread dopo la sua terminazione.
In alternativa, puoi fare in modo che il thread sia freeOnTerminate (o
qualcosa di simile) e notifichi al main thread come è andata
l'elaborazione in un metodo da sincronizzare (probabilmente più
semplice e corretto). Vedi l'help e l'esempio di TThread.Terminated
Saluti
Paolo Arosio

scusate ma una cosa non capisco, una progressbar visualizza la
percentuale di incremento su un determinato campo, ma se i limiti
dello stesso sono indeterminati cosa rappresenterà?


Probabilmente si parla di una "circular progress bar" che fa scorrere un 
corsure dall'inizio alla fine e poi ricomincia indefinitamente.
-- 
morde
D5,D6,D7
Firebird 2.1
QT 4.7.0 (MingW) QT Creator 2.1