Asynchronous Paradigm

From Overbyte
Revision as of 19:08, 20 February 2006 by Arno (talk | contribs) (→‎Non-Blocking)
Jump to navigation Jump to search

To Block or not to Block

Non-Blocking

Think of windows programming. It's event driven. Your application doesn't wait in a loop polling the status of a button until it is pressed, instead it gets notified about a button click, in other words an event is triggered. You simply place code to be executed in the event handler. When the user hits the button event OnClick is fired and your code is run. Very efficient, this is called event-driven or non-blocking or asynchronous (async).

When you call an asynchronous method it will return immediately, regardless whether it has finished or not, an event handler will be called later when the method has finished. This also means that your application is capable to do something else in the meanwhile so the following pseudo code suitable for blocking internet components would NOT work with non-blocking ICS components:

Connect
Send(Something) 

Because Connect would return immediately without even making sure it has finished successfully and next line would be executed at once. Thus Send(Something) would the fail because it's trying to send data even though there is no connection established to the server yet.


So you need to design your program a bit different. Just like OnClick, the ICS components provide many events allowing you to control program flow. You have to call a method and from then on you rely on events. So you just call Connect, that's it:

procedure MySendData;
begin    
    Connect
end;

Later when method Connect has finished event OnConnect will fire where you can safely send data.

procedure OnConnect(Error: Word);
begin
    if Error = 0 then
        Send(Something)  
end;

Very easy, isn't it?

Blocking

Blocking or synchronous (sync) methods do NOT return until they have finished, so our first code sample would work:

Connect
Send(Something)     

Connect won't return until the connection to the server has been established or an error occured (a timeout may take a very long time ;-). While the program tries to connect it cannot do anything else, it blocks execution even though method connect may just sit there waiting for a server response.

Blocking vs. Non-Blocking

Due to the non-blocking nature of ICS it is very easy to handle hundreds of concurrent connections within a single thread.

I give you a pseudo example:

procedure MySendData;
var
    I : Integer;    
begin    
    for I := 0 to List.Count -1 do
        TWSocket(List[I]).Connect;
end;
procedure OnConnect(Sender: TObject; Error: Word);
begin
    if Error = 0 then
        TWSocket(Sender).Send(Something)  
end; 


With blocking components multiple concurrent connections are only possible if each connection is executed in its own thread context. But threads must be created, freed, synchronized or managed by so called thread pools, this all doesn't speed up things as you can imagine.