Newsgroup: it.comp.lang.delphi
Titolo: Problema con thread..

Ciao a tutti.
Ho creato in una apposita unit (chiamiamola con molta fantasia Unit2)un
thread che mi permette di connettermi ad un sito.
type
 MioHttp = class(TThread)
 protected
 RigaListview :integer;
 Miocookie,Username,Pwd:string;
 St: TstringStream;
    procedure Execute;override;
    procedure PostaDati(Dato1:string ;Dato2:string);
    procedure Parse (PagWeb : String);
  end;
Da pulsante io chiamo la procedura Execute con miothread.Resume , il thread
viene creato e la connessione con il sito pure,i dati della pagina web pure,
tutto Ok.
Ora pero' io vorrei richiamare con un altro pulsante la procedura PostaDati
perche' mi serve mandare altri dati alla pagina web con un post  quando
l'utente vuole e non automaticamente come ho fatto prima nella procedura
Parse , ma non riesco a richiamarla dalla unit1con un semplice PostaDati
(x,y) nel Button.Click.
Spero di essere stato chiaro, insomma come si fa a richiamare una procedura
creata da un thread?
Grazie.

 thread che mi permette di connettermi ad un sito.[CUT]
Ciao,
tu probabilmente chiami il metodo del thread quando questi è già terminato.
E soprattutto fai confusione fra codice chiamato da dentro il thread e
procedura appartenente all'oggetto thread che chiami dall'esterno.
In primo luogo ti consiglierei di vedere un po' l'SDK di windows che trovi
anche dentro al delphi che usi.
Una soluzione sarebbe quella di far eseguire al thread una azione alla
ricezione di un messaggio a lui postato. Qui devi vedertela con la coda dei
messaggi, il prelievo e la loro gestione.
Però ora ti voglio consigliare una cosa meno difficoltosa.
Come ti ho scritto fai confusione fra procedure chiamate dal thread e quelle
appartenenti all'oggetto TThread ma chiamate dall'esterno.
Per prima cosa, se vuoi che il thread resti attivo, devi creargli un loop al
suo interno... non infinito, tipo:
While not terminated do
begin
...
end;
Ti basterà, per farlo terminare, richiamare il metodo Terminate, sia
dall'interno che dall'esterno.
E', secondo me, non corretto, in questo caso, creare un thread con
un'operazione preimpostata.
Devi crearti una specie di messaggi. Ti faccio un esempio che poi adatterai
al tuo caso:
1. Rendi pubblica una proprietà da un tipo enumerated.
Type
TMYThreadActions = (maEmpty, maSettings, maUrlget, ma Urlpost);
Private
fMyActions: tMyThreadActions;
public
Property MYActions: tMYThreadActions read fMYActions;
2. Inizialmente, nel costruttore, imposti la variabile a maEmpty;
3. Per le due altre operazioni, maUrlGet, maUrlPost, dovresti dichiarare
delle variabili a loro dedicate, o, se non hai esigenze diverse, una
soltanto che ospiti la stringa passatagli dal richiamo delle procedure.
Devi per ogni procedura, dichiarare una visibile dall'esterno che controlli
lo stato di quella variabile di prima e si occupi di impostare la variabile
interna al thread ad essa dedicata, e infine, liberare la variabile
dell'azione. E una procedura interna che compia l'azione. Altresì
predisporre degli eventi che comunichino i risultati a chi usa l'oggetto
thread.
Ti faccio un esempio.
Type
tMyUrlgetEvent = Procedure (sender:tObject; result:String) of object;
Private
fUrlGet: String;
fUrlgetEvent: tMyUrlgetEvent;
Procedure IntUrlGet(aUrl:String);
Public
Procedure Urlget(aUrl:String);
Property OnUrlGetResult: tMyUrlgetEvent read fUrlgetevent write
fUrlgetEvent;
...
// Procedura interna al Thread e privata
Procedure tThread1.IntUrlget(aUrl:String);
var
Result:string;
begin
// Compie l'azione di Get sull'indirizzo passatogli
Result:= idHttp1.Get(aUrl);
// Restituisce il risultato attraverso l'evento
if Assigned(fMyUrlgetEvent) then fUrlgetEvent(self,result);
// Libera la coda singola affinché possa venire processata un'altra azzione
fMyActions:= maEmpty;
end;
// Procedura pubblica
Procedure TThread1.Urlget(aUrl:String);
begin
// Aspetta che il thread sia libero
While fMyActions<> maEmpty do;
// Occupa il thread con la nostra azione di settaggio parametri
fMyActions:= maSettings;
// Passaggio del nostro url alla variabile interna
fUrlget:= aUrl;
// Completamento e settaggio dell'azione
fMyActions:= maUrlget;
end;
// Ecco come cambia l'execute del thread
Procedure TThread1.Execute;
begin
fMyActions:= maEmpty;
While not Terminated do
begin
Case fMyActions of
maUrlget: IntUrlget(fUrlget);
maUrlpost: IntUrlpost(fUrlpost);  // questo lo scrivi tu
end;
end;
Su questo esempio potresti sviluppare il thread con una coda di azioni
preparando un oggetto ad hoc... per non far aspettare la liberazione del
thread ogni qualvolta venga chiamato un suo metodo e il thread è già
occupato con un'altra azione. Ma sinceramente, ho scritto troppo e non mi va
ancora di dilungarmi. Se hai bisogno chiedi. Se ho fatto qualche errore, di
dimenticanza o di battitura, perdonami... spero comunque il concetto sia
chiaro.
Ciao
Giuseppe

 ha scritto nel messaggio
news:5EhJb.38369$_P.16...@news4.tin.it...
