Asynchronous Calls
From RemObjects Software
This is a RemObjects SDK Feature topic
Feel free to add your notes to this topic below.
Since version 3.0, RemObjects SDK has provided the option to execute requests against remote services in an asynchronous fashion.
When performing normal (synchronous) calls against your server, the thread making the server call will block then wait until the request has been executed on the server and a response has been received. In most cases, this is the preferred way to make calls, as it closely resembles the paradigm you are used to from calling local methods within your application.
In some scenarios though, it might be helpful to trigger an action on the server, but continue with local processing as the server executes the request, without waiting for the response first. The response could be collected at a later time, or might even not be relevant at all.
RemObjects SDK provides an infrastructure for making such asynchronous calls to your services. Asynchronous calls are handled entirely on the client side and in the communication layer of the server, making them work against your existing servers without change.
Async Interface Files
Support for asynchronous calls starts with a special _Async interface file.
Similar to the familiar _Intf file, this unit provides a special version of your server interfaces prepared for asynchronous use. Every service method defined in a service interface will be split in two parts for this, one method prefixed with Invoke_ that will initiate the request, and one prefixed with Retrieve_ that will complete a previously invoked request and retrieve any results. (Methods that do not contain any out or result parameters will only be represented by an Invoke_ method).
For example, if your original Delphi service defined a Sum method:
INewService = interface function Sum(A: Integer; B: Integer): Integer; end;
this method would result in two split methods in the async interface:
INewService_Async = interface(IROAsyncInterface) procedure Invoke_Sum(A: Integer; B: Integer); function Retrieve_Sum: Integer; end;
In your application code you would call Invoke_Sum(5,10), which would initiate the request to the server but return right away without waiting for the result. Your client application would continue performing other tasks and, at some point in time, call x := RetrieveSum() to obtain the actual result.
Working with Async Interfaces
In addition to the split invoke/retrieve methods of your service, the async interface also contains a number of helpful properties it inherits from IROAsyncInterface. The AnswerReceived property will specify if an answer for the previous Invoke call has been received yet.
You can use this to determine whether your code should call the Receive_ method yet. Calling Receive_ when an answer is yet not available will raise an EROAsyncNoAnswerYet exception.
Similarly, the AnswerReceivedEvent property can be used on channels that support active asynchronous calls to get a Win32 event object that will be triggered when an answer comes in.
Under the Hood of Asynchronous Calls
How asynchronous method calls are handled internally depends to a large degree on the channel type.
Some channels, including the new Super TCP Channel, the UDP Channel and the Email Channel, provide active support for asynchronous calls. They know how to transmit an async request to the server and to actively handle receiving a response.
Other channels, including the standard HTTP and TCP channels are unaware of asynchronous requests. When executing an async call on one of these channels, the asynchronous behavior will be simulated on the client side, by spawning of a worker thread that performs the actual (synchronous) call and waits for the response.
This difference is handled internally by the asynchronous proxy, so your application code will not know the difference.
Generating the Async_ interface unit
Since most applications do not make use of asynchronous calls, the Async_ interface unit will not be generated or regenerated automatically on every compile. Instead the RemObjects SDK Menu provides a "Regenerate Async Unit from RODL" menu item to manually create or recreate this unit, as needed.
See Also
Product: RemObjects SDK
Current version: RemObjects SDK 'Vinci' (5.0)
Lists — Glossary — Features — How To — Components — Tools — Samples — Articles — Architecture — Issues
