Newsgroup: it.comp.lang.delphi
Titolo: Sospendere momentaneamente TidTCPServer.Execute

E' possibile come da oggetto? Su Google non ho trovato niente del genere.
Dovendo aggiornare dei dati che cambiano proprio nell'evento OnExecute 
dovrei poterlo fare escludendo che questi si modifichino proprio in quel 
momento.
La cosa potrebbe generare problemi ai client che richiedono dei dati?
Valter

Mi spiego meglio come richiesto:
se devo gestire degli eventi dall'interno dell'OnExecute il problema non 
dovrebbe porsi ma utilizzo anche un TTimer che ogni tot scansiona una lista 
di tutti i client collegati e fa una sottrazione tra l'ora attuale e 
l'ultima ora di connessione dei client stessi. Quelli che non si sono 
ripresentati entro un periodo che mi sono prefissato vengono considerati 
persi ed i dati che avevano ricevuto vengono distribuiti ad altri client.
Trattandosi di un "intervento esterno" del TTimer si potrebbero verificare 
degli aggiornamenti del db proprio in quel momento causati dall'Execute ed 
incasinarmi tutto.
Quindi pensavo di sospendere durante la verifica chiamata dal TTimer 
qualsiasi operazione dell'Execute.
Attualmente ho inglobato tutto il codice dell'Execute in un blocco 
controllato da una booleana globale. Quando il TTimer scatta ne cambia il 
valore ed il server non processa i dati dell'Execute. L'operazione dovrebbe 
essere rapida ma il mio dubbio č come si comportano i client che in quel 
momento richiedono o cercano di rispedire al server i dati elaborati. 

 E' possibile come da oggetto? 
Perché vuoi farlo ? non ha senso.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 un TTimer che ogni tot scansiona una lista 
Usa un thread, non un timer e sincronizzalo.


 Usa un thread, non un timer e sincronizzalo.
Ok, ho dovuto approfondire l'argomento perchè non avevo mai usato un thread
sincronizzato o meno nè il PostMessage (che vergogna). Ho trovato
un'interessantissimo tutorial in rete che fornisce i primi rudimenti ed è
scritto chiarissimo. Domani lo posto per chi fosse interessato e
completamente all'oscuro come me.
Volevo chiedervi se sono sulla strada giusta, quando avete tempo mi dareste
un'occhiata a questo test?
Mi restituisce alcuni comportamenti errati:
non appena avvio le operazioni cliccando button1 avvio anche il thread
secondario che dovrebbe intervenire dopo 5 secondi...ma il contatore subito
conta fino a sei, tutte le seguenti fino a cinque come impostato...mi sfugge
una banalità?
se trascino il form con il mouse "perdo" delle stringhe nei memo ed il
contatore sfalsa (colpa forse degli sleep()?) e soprattutto se non inserisco
application.processmessage dopo i postmessage non visualizzo nulla.
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TThreadTest=class(TThread)
  private
    FHandle: HWND;
  protected
    procedure Execute; override;
    procedure Attesa; virtual; // deve essere dichiarata VIRTUAL?
  public
    procedure AssignHWND;
  end;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Memo1: TMemo;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure WMStartThread(var Msg: TMessage); message WM_USER+100;
    procedure WMInThread(var Msg: TMessage); message WM_USER+101;
    procedure WMUpdateDB(var Msg: TMessage); message WM_USER+102;
    procedure WMStopThread(var Msg: TMessage); message WM_USER+103;
  private
    { Private declarations }
     FNewThread: TThreadTest;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  FNewThread := TThreadTest.Create(false);
  FNewThread.AssignHWND;
  for i := 1 to 2000000000 do
  begin
    memo1.Lines.Add('Il server processa i dati');
    label1.Caption := inttostr(i);
    application.ProcessMessages;
    sleep(1000);
  end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
  FNewThread.Terminate;
end;
procedure TForm1.WMStartThread(var Msg: TMessage);
begin
  Memo1.Lines.Add('Stop Thread Primario, Start Thread Secondario');
end;
procedure TForm1.WMInThread(var Msg: TMessage);
begin
  Memo2.Lines.Add('In Thread Secondario');
end;
procedure TForm1.WMUpdateDB(var Msg: TMessage);
begin
  label2.Caption := inttostr(Msg.WParam);
  application.ProcessMessages;
end;
procedure TForm1.WMStopThread(var Msg: TMessage);
begin
  Memo1.Lines.Add('Stop Thread Secondario, Start Thread Primario');
end;
// TThreadTest
procedure TThreadTest.AssignHWND;
begin
  FHandle := Form1.Handle;
end;
procedure TThreadTest.Execute;
begin
  while not terminated do
  begin
    // ogni 5 secondi fermo il thread primario
    // per aggiornare il database
    sleep(5000);
    PostMessage(FHandle, WM_USER+100, 0, 0);
    Synchronize(Attesa);
  end;
end;
procedure TThreadTest.Attesa;
var
  a: integer;
begin
  // il ciclo simula l'aggiornamento del db
  for a := 1 to 3 do
  begin
    PostMessage(FHandle, WM_USER+101, 0, 0);
    PostMessage(FHandle, WM_USER+102, a, 0);
    application.ProcessMessages;
    sleep(1000);
  end;
  a := 0;
  PostMessage(FHandle, WM_USER+102, a, 0);
  application.ProcessMessages;
end;
end.

 sincronizzato o meno
Quando parlo di sincronizzare i thread intendo usare un oggetto di
sincronizzazione, come una critical section, un mutex, un evento, ecc...
Dati due thread A e B:
tempo 0---------------------------------------------------->
    A ----------->
    B ----------->
..procedono ognuno per conto proprio...
All'istante 1 A acquisisce una critical section per compiere una
determinata operazione (x), B cerca di acquisirla all'istante 2 per fare
un'operazione sugli stessi dati:
tempo 0-----------1--------------2------------3-------4-----------
    A ----------->!xxxxxxxxxxxxxxxxxxxxxxxxxxx-------------->
    B -------------------------->?............xxxxxxxx------>
..B trova la risorsa bloccata quindi resta in attesa fino al suo sblocco
che avviene all'istante 3, quindi acquisisce la critical section e la
elabora rilasciandola all'istante 4...


 sincronizzazione, come una critical section, un mutex, un evento, ecc...
Fortunatamente, da ieri, so di cosa parli anche se ci devo ovviamente 
studiare.
Ma nel frattempo ho aggiunto il thread secondario alla mia applicazione 
server e parrebbe funzionare.
Quando in pratica faccio eseguire il codice del thread secondario al thread 
primario tramite Sinchronize() il Server smette di inviare dati ed il Client 
di riceverli. Al termine dell'aggiornamento (al momento rappresentato da un 
PostMessage su una Memo "sto aggiornando il database, il Server è sospeso" 
ed uno sleep() di qualche secondo) il Server riprende ad inviare dati ed il 
Client a riceverli e questo avviene ciclicamente.
Perchè non trovi indicato questo tipo di TThread? Un'operazione non esclude 
l'altra?
V.