Newsgroup: it.comp.lang.delphi
Titolo: Function

Al click su un Button richiamo una funzione la quale effettua numerose
iterazione.
Esiste la possibilita' di interrompere l'esecuzione di tale funzione, ovvero
esiste un comando che termina la funzione. Volevo fare un secondo Button
(del tipo annulla), che interrompesse la function.
Volevo evitare l' utilizzo di una variabile condivisa che la mia function
testa ad ogni iterazione e che viene settata quando premo button2.
Grazie

xche non un thread?
Bye
AS

 testa ad ogni iterazione e che viene settata quando premo button2.
Soluzione che tra l'altro non funzionerebbe, dato che entrambe le funzioni
sono sullo stesso thread e la seconda non partirebbe fintanto che non
finisce la prima...
Ti consiglio l'utilizzo di Thread, che anche se non banale e' la cosa piu'
indicata.
Ciao!                Nicola {MSX} Lugato
P.S. Scusa se ti ho risposto anche privatamente, ho sbagliato tasto su
outlook, volevo rispondere sul NG :) scusa l'intrusione

 button2. 
Come ti hanno scritto, l'utilizzo di un thread e' molto piu' elegante e
corretto. Potresti tuttavia utilizzare Application.ProcessMessages
all'interno della prima funzione (quella lunga) per permettere la gestione
degli eventi (e quindi di rispondere all'evento del pulsante "Annulla"). 
var ANNULLA: BOOLEAN
TForm1.Button1Click (Sender: TObject);
Begin
ANNULLA := FALSE;
{ magari qui inibisci (Enabled = false) i controlli che non dovrebbero
essere abilitati durante la funzione, perche' con
Application.ProcessMessages, l'utente puo' cliccare liberamente e gli
eventi vengono scatenati comunque) }
// for i:= 0 to iterazioni do begin
// calcoli....
    Application.ProcessMessages;
    if ANNULLA then begin
      // riporta il programma in uno stato "sicuro"
      exit; // esce dalla funzione.
    end;
end;
TForm1.Button2Click (Sender:TOBject);
Begin
  ANNULLA := TRUE;
End;
Ciao! 
Davide DG.
-- 
All resistance is futile! Prepare to be disassembled !

 testa ad ogni iterazione e che viene settata quando premo button2.
Hai qualche motivo particolare per scartare questa soluzione ?
Forzando la lettura dei messaggi ad ogni iterazione, puoi
facilmente gestire il tutto.  L'uso di un thread separato non
ha senso se il thread principale si deve limitare ad eseguire
una sola operazione e questa deve essere interrompibile (come
intuisco da cio' che scrivi).
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 intuisco da cio' che scrivi).
La soluzione del controllo di una variabile ad ogni ciclo non è
assolutamente sbagliata (su molti testi, anche di SO, viene utilizzata per
lo sviluppo di molti algoritmi) tuttavia mi sento di sconsigliarla a causa
dell'onerosità che essa richiede quando è accompagnata dal metodo
ProcessMessages di TApplication. Forzare la propria applicazione a servire
la coda dei suoi messaggi significa farle svolgere un carico di lavoro di N
volte superiore rispetto al normale.
Prendo come esempio un caso estremo ... soluzione con 2 thread separati:
function StartThread( par: Pointer ): dWord; stdcall;
begin
  tempo := getTickCount();
  for i := 1 to 999999999 do begin
  end;
  Application.MessageBox(pChar(IntToStr(GetTickCount() -
tempo)),'prova',IDOK);
end;
procedure TForm1.Button1Click(Sender: TObject);
var tid: dWord;
begin
  hThread := CreateThread(nil,0,@StartThread,nil,0,tid);
end;
Il codice del button2 potrebbe contenere chiamate tipo SuspendThread().
Provate ora ad eseguire un codice monothread contenente le seguenti
chiamate:
procedure TForm1.Button1Click(Sender: TObject);
var tid: dWord;
begin
  tempo := getTickCount();
  for i := 1 to 99999999 do begin
      application.ProcessMessages;
  end;
  Application.MessageBox(pChar(IntToStr(GetTickCount() -
tempo)),'prova',IDOK);
end;
Io ottengo risultati di 361 millisecondi con la soluzione 1 contro i 5150
della seconda soluzione.
--
- Carlo -
cbertu81(at)libero(dot)it