<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">Le 25/10/2012 13:07, Bernd a écrit :<br>
very nice indeed and readable even on pseudo-code, but ...<br>
</div>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
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</pre>
</blockquote>
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.<br>
Furthermore, all requests coded until now have to be moved outside
of the procedures or events holding them: a lot of work<br>
What if:<br>
<pre wrap="">pocedure OnEverythingGetsStarted;
<big><big><b><small>var
AHandles: PWOHandleArray;</small></b>
</big></big><b> </b><b><big>Res: DWORD;</big></b>
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;
</pre>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
end;
procedure OnTimer;
begin
if State = WAITING then begin
Disconnect
State := IDLE</pre>
</blockquote>
Timer.enabled := False;<br>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
enable the disabled buttons
end;
end;
procedure OnReceive(S: TLSocket);
begin
Answer := S.GetMessage()</pre>
</blockquote>
forget about the rest of the procedure and do instead:<br>
DoWhatEverBeforeProcessData(Answer);<br>
Event.SetEvent; // event signaled<br>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
case Answer of
'foo': begin
DoThis();
SendAnotherCommand();
end
'bar': begin
DoThat();
SendSomeThingDifferent();
end</pre>
</blockquote>
.. I have dozens of messages to process in the internal
protocol<br>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
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.</pre>
</blockquote>
Anyway, I can agree with this above.<br>
But the application has to be re-engineered.<br>
<br>
<blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
type="cite">
<pre wrap="">
</pre>
</blockquote>
<br>
</body>
</html>