Le 25/10/2012 13:07, Bernd a écrit :
very nice indeed and readable even on pseudo-code, but ...
Here is an alternative way to implement it (this one can even reply
and have a conversation of multiple commands going forth an back
between the client and server):

pocedure OnEverythingGetsStarted;
begin
    if State = WAITING then exit;
    State := WAITING
    maybe also disable some buttons that might interfere
    open the connection
    send the request
    start the timeout timer
    // return from that event
this is exactly what I have to avoid: user gains control on screen. A workaround is to disable the window itself. But then another timer is needed to ensure that whatever happens or NOTHING happens, control will return back to the starting point. Furthermore, all requests coded until now have to be moved outside of the procedures or events holding them: a lot of work
What if:

pocedure OnEverythingGetsStarted;
*var
  AHandles: PWOHandleArray;*
*   **Res: DWORD;*
begin
   if State = WAITING then exit;
   State := WAITING
   maybe also disable some buttons that might interfere
   open the connection
   Event.ResetEvent;  // not signaled
   send the request
   start the timeout timer
AHandles[0] := Timer.Handle;
   AHandles[1] := Event.Handle; // posted by the OnReceive
 event
   Res:=WaitForMultipleObjects(2, @AHandles, False, Timeout);
   // wait for first reset, not interested for all
   case Res of
     ... continue processing depending of the answer or no answer
   end;
end;

end;

procedure OnTimer;
begin
   if State = WAITING then begin
     Disconnect
     State := IDLE
            Timer.enabled := False;
     enable the disabled buttons
   end;
end;

procedure OnReceive(S: TLSocket);
begin
   Answer := S.GetMessage()
forget about the rest of the procedure and do instead:
        DoWhatEverBeforeProcessData(Answer);
        Event.SetEvent;    // event signaled
   case Answer of
   'foo': begin
      DoThis();
      SendAnotherCommand();
   end
   'bar': begin
      DoThat();
      SendSomeThingDifferent();
   end
        .. I have dozens of messages to process in the internal protocol
   else begin
      DoWhateverNeedsToBeDone();
      S.Disconnect;
      State := IDLE;
      enable the disabled buttons
   end;
end;

This will never block and never freeze and never eat any unneeded CPU
cycles and it is les code than messing around with the eventers and
CallAction directly and also less code than low level programming
against sockets and/or winsock2 directly.
Anyway, I can agree with this above.
But the application has to be re-engineered.


--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to