Newsgroup: it.comp.lang.delphi
Titolo: pausa in un thread

Salve.
Ho un thread che esegue una operazione su un tclientsocket asincrono:
assegna un ip e una porta
lo apre
se la connessione è attiva, imposto il returnvalue a zero, altrimenti a -1
Il mio problema è che la esecuzione del thread è talmente veloce che il
clisocket non ha il tempo per diventare attivo e il th, alla prima
esecuzione,  mi ritorna sempre -1.
Ho provato a cercare nella api di winsozz un modo per fermare per qualche
istante la esecuzione del thread dopo la tentata apertura del socket, ma cio
che ho trovato come mutex, semafori e alcune funzioni sono relativi alla
concorrenza di threads multipli
Una api interessante sembrerebbe WaitMessage:
The WaitMessage function yields control to other threads when a thread has
no other messages in its message queue. The WaitMessage function suspends
the thread and does not return until a new message is placed in the thread's
message queue.
ma non credo che la attivazione del clisocket inivvi un messaggio al thread
senza che io gli dica in qualche modo di farlo.
Dovrei ad esempio associare all'evento connect del clisocket l'invio di un
messaggio al thread?
Per dirla in codice:
MyThread.execute;
begin
   returnValue := -1;
   FCliSocket.Port := CurrentPort;
   FCliSocket.Address := CurrentIp;
  Open;
  // qui andrebbe una pausa
  if FCliSocket.Active then
     returnvalue := 0
Qualche suggerimento?
Tnx
A.

 Qualche suggerimento?
MyThread.Execute
begin
    ReturnValue:=-1;
    FCliSocket.Port := CurrentPort;
    FCliSocket.Address := CurrentIp;
   Open;
    while (not Terminated) and (not FCliSocket.Active) do
            Application.ProcessMessages;
    if not Terminated then
        ReturnValue:=0;
end;
Così non va bene per il tuo caso?
Se la risposta è: "no", non potresti attendere che il Server ti invii un
messaggio per
notificarti l'avvenuta connesione?
L'evento "OnConnect" del TClientSocket non puoi utilizzarlo?
Fammi sapere.
Saluti

> Così non va bene per il tuo caso?
Purtroppo no.
Il tutto dovrebbe essere gestito dal thread senza interventi esterni.
Potrei assegnare al socket un gestore interno al th per evento OnConnect,
ripristinando in uscita quello originale, ma se non ho una response del
server, chi dice al th di "autoterminarsi"?
Ovviamente con un timeout...
Grazie comunque xche non avevo pensato alla possibilita di cambiare i
gestori degli eventi dell'skt nel thread per poi riassegnare quelli di
default in uscita dal th stesso....
Forse una soluzione potrebbe passare x questa strada.
A.

 Ovviamente con un timeout...
Se all'atto dell'attivazione del Client Socket acquisici un mutex,
poi cambi il gestore dell'evento OnConnect del socket con uno
interno al thread.(ovviamente riprisinando quello originale al termine)
A questo punto, dal metodo Execute del thread fai un bel
WaiForSingleObject(MutexHandle,TimeOut).
Ora, gli scenari possibili sono 2:
1) Viene chiamato il tuo gestore per l'OnConnect
    Il ritorno dalla WaitFor... non sarà per colpa del TimeOut.
    Qui provvedi al rilascio del mutex acquisito in partenza.
    Ciò è seguito dal fatto che il valore di ritorno del Thread
    sarà 0.
2) Ritorno dal wait TimeOut
    Rilasci il mutex che precedentemente hai acquisito.
    A questo punto il valore di ritorno del Thread sarà -1
Può funzionare?

tnx!!!!
potrebbe. provo e ti faccio sapere, ma non oggi...
Bye
A.


Se ho capito bene, potresti utilizzare un evento da alzare
nell'OnConnect di TClientSocket.
var
  ConnectEvent: THandle;
  WS: Cardinal;
queste due porzioni di codice sono la creazione e la distruzione
dell'evento (le chiami una volta sola):
ConnectEvent := CreateEvent(nil, False, False, '');  //creazione
CloseHandle(ConnectEvent); //distruzione
e nella tua execute:
MyThread.execute;
begin
   returnValue := -1;
   FCliSocket.Port := CurrentPort;
   FCliSocket.Address := CurrentIp;
  Open;
  // qui andrebbe una pausa
  WS := WaitForSingleObject(ConnectEvent, 5000); // 5000 ms di attesa
  if WS = WAIT_OBJECT_0 then begin
   	 //l'evento č stato alzato returnvalue presumibilmente :=0
  end else begin
    	//Timeout non č arrivato l'evento
  end;
e infine nel TClientSocket.OnConnect:
SetEvent(ConnectEvent);

Carmine & Lopan: tnx!
2 modi diversi che provero' senza meno.
A.

 concorrenza di threads multipli
Non son certo, letti gli altri suggerimenti, di aver capito bene. Se
cio' che ti serve e' una attesa incondizionata direi che Sleep fa al
caso tuo (eventualmente da richiamare + volte con brevi intervalli e un
modo di timeout.
while ((retries < TROPPI) and not(ESuccessoQualcosa)) do begin
  Inc(retries);
  Sleep(5);
end;
Saluti
Paolo Arosio

 end;
Provato ma non applicabile per vari motivi.
Grazie comunque.
A