# ...Async\_Ex service functions

**URL:** https://talk.remobjects.com/t/async-ex-service-functions/27616
**Category:** Remoting SDK
**Tags:** delphi
**Created:** [December 12, 2022, 9:24am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616 "2022-12-12T09:24:04Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [December 12, 2022, 9:24am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/1 "2022-12-12T09:24:04Z")

</div>

hi, i’ve started playing around with the Async\_Ex service function calls and have a few questions:

- the create:  
class function Create(const aUrl: string; aDefaultNamespaces: string = ‘’): IProxyService\_AsyncEx; overload;  
it seems that i can’t get this one to work, i do include the /BIN but i guess it does not resolve to the right channel… any prerequisites using this?

- channel and message:  
my these be shared when using the async\_ex functions or do these have to have their own channel and message?

- the callback:

- is this called in the main thread or do i need to foresee threaded entry?
- can i have multiple async\_ex.beginxxx calls all using the same callback?
- if so what is the lifetime of the Endxxx call of (const aRequest: IROAsyncRequest)?
- if i can’t use the same callback for multiple beginxxx calls, do i always nil the aRequest or not? (in the photo sample you check the intf: if aRequest = ClientForm.fDownload then ClientForm.fDownload := nil;)

- any other things to take into account?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [December 12, 2022, 10:54am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/2 "2022-12-12T10:54:26Z")

</div>

Hi,

Check the `Phone Photo Server` sample - it shows usage of AsyncEx interfaces.

> [@marcantheunis](#):
>
> the create:  
> class function Create(const aUrl: string; aDefaultNamespaces: string = ‘’): IProxyService\_AsyncEx; overload;  
> it seems that i can’t get this one to work, i do include the /BIN but i guess it does not resolve to the right channel… any prerequisites using this?

You should include full URL with `/Bin` - it will allow to detect valid message.  
general rules - you should include desired channel/message into uses section.

Channels/Messages contain code like

```auto
ROUrlSchemaParser.ProtocolHandler[URL_PROTOCOL_HTTP] := TROIndyHTTPChannel;

```

```auto
ROUrlSchemaParser.MessageHandler['bin'] := TROBinMessage;

```

it is used for detecting what channel/message should be used.  
you may add registration manually for desired channel if it is missed it.

> [@marcantheunis](#):
>
> channel and message:  
> my these be shared when using the async\_ex functions or do these have to have their own channel and message?

own channel/message are used for AsyncEx fro avoiding AV issues when the same data is read/wtitten from different threads.  
You can retrieve channel/message from [IROAsyncRequest](https://docs.remotingsdk.com/API/Delphi/Interfaces/IROAsyncRequest/) interface.

> [@marcantheunis](#):
>
> is this called in the main thread or do i need to foresee threaded entry?

it is called in background thread

> [@marcantheunis](#):
>
> can i have multiple async\_ex.beginxxx calls all using the same callback?

You can use the same callback method for handling begin\* methods.

for example - you have `BeginSum` and `BeginGetServerTime` methods. if same callback is used for both methods you have to call `EndSum` or `EndGetServerTime` in that callback. ofc, you can put some additional info into UserData and detect valid method, but I think better to have own callback per method.

> [@marcantheunis](#):
>
> if so what is the lifetime of the Endxxx call of (const aRequest: IROAsyncRequest)?

server response is stored in object associated with IROAsyncRequest. this object is passed to your callback method.

> [@marcantheunis](#):
>
> if i can’t use the same callback for multiple beginxxx calls, do i always nil the aRequest or not? (in the photo sample you check the intf: if aRequest = ClientForm.fDownload then ClientForm.fDownload := nil;)

in this sample we allow only one download request so we cancel previous one:

```delphi
  if (fDownload <> nil) then fDownload.Cancel;
...
  fDownload := GetService.BeginDownloadPhoto(lItem.Name,Callback_DownloadPhoto,lItem);

```

so we clear `fDownload` once download callback was finished.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [December 12, 2022, 11:57am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/3 "2022-12-12T11:57:04Z")

</div>

> Channels/Messages contain code like
> 
> ```auto
> ROUrlSchemaParser.ProtocolHandler[URL_PROTOCOL_HTTP] := TROIndyHTTPChannel;
> 
> ```
> 
> ```auto
> ROUrlSchemaParser.MessageHandler['bin'] := TROBinMessage;
> 
> ```
> 
> it is used for detecting what channel/message should be used.  
> you may add registration manually for desired channel if it is missed it.

the uses clause is ok, but the channel does not get recognised, we use plain tcp by the way, not https, so my test url is ‘localhost:8888/BIN’  
is this supposed to work?

> it is called in background thread
> 
> > [@marcantheunis](#):
> >
> > can i have multiple async\_ex.beginxxx calls all using the same callback?
> 
> You can use the same callback method for handling begin\* methods.

so if i execute 5 beginAAA calls (so the same function) all with the same callback interface, and since the callback is being called threaded, i should include thread code that will synchronise with main thread yes? or will the the callback for the beginAAA func be like a fifo callback?

> in this sample we allow only one download request so we cancel previous one:
> 
> ```auto
> if (fDownload <> nil) then fDownload.Cancel;
> ...
> fDownload := GetService.BeginDownloadPhoto(lItem.Name,Callback_DownloadPhoto,lItem);
> 
> ```
> 
> so we clear `fDownload` once download callback was finished.

no i was talking about the callback procedure which has:  
finally  
if aRequest = ClientForm.fDownload then ClientForm.fDownload := nil;

so this frees the iroasyncrequest but only if it was the one that was created in the beginAAA call, but why only if it is the same? since the call has ended, shouldn’t it be always freed?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [December 12, 2022, 12:12pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/4 "2022-12-12T12:12:05Z")

</div>

> [@marcantheunis](#):
>
> the uses clause is ok, but the channel does not get recognised, we use plain tcp by the way, not https, so my test url is ‘localhost:8888/BIN’  
> is this supposed to work?

you should use **tcp://localhost:8888/BIN**

> [@marcantheunis](#):
>
> so if i execute 5 beginAAA calls (so the same function) all with the same callback interface, and since the callback is being called threaded, i should include thread code that will synchronise with main thread yes? or will the the callback for the beginAAA func be like a fifo callback?

it shouldn’t matter because you receive `aRequest` in callback method.  
so you will have 5 background threads with

- callback(aRequest1)
- callback(aRequest2)
- callback(aRequest3)
- callback(aRequest4)
- callback(aRequest5)

in the `Phone Photo Server` sample we use `PostMessage` for passing data from background threads to main thread.

> [@marcantheunis](#):
>
> so this frees the iroasyncrequest but only if it was the one that was created in the beginAAA call, but why only if it is the same? since the call has ended, shouldn’t it be always freed?

it isn’t freed interface, it just clear private variable of TClientForm [and decrease reference count] so interface will be correctly destroyed.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [December 12, 2022, 12:32pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/5 "2022-12-12T12:32:13Z")

</div>

ok thx for the info!

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [December 14, 2022, 8:46am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/6 "2022-12-14T08:46:23Z")

</div>

Evgeny,

consider this:  
var intf : IROAsyncRequest

intf := beginAsync\_ex();  
…  
intf := beginAsync\_ex();  
…  
intf := beginAsync\_ex();  
…

so now i have 3 requests stored in same var intf…

callback(const aRequest: IROAsyncRequest);

1. so this is a const param, i can’t nil this, so the async\_ex object will take care of this?

2. since i putted all beginAsync\_ex() result into the same var i will have created dangling interface references yes?  
if so i need to hold some kind of list of them?  
or can i simply ignore the interface result of the beginAsync\_ex call?  
in fact do i need the interface reference at all?

tia!

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [December 14, 2022, 9:38am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/7 "2022-12-14T09:38:20Z")

</div>

Hi,

> [@marcantheunis](#):
>
> so now i have 3 requests stored in same var intf…
> 
> callback(const aRequest: IROAsyncRequest);
> 
> 1. so this is a const param, i can’t nil this, so the async\_ex object will take care of this?

No issue at all. this means that you can work only with last request.  
actual `IROAsyncRequest` is stored internally and it will be passed to your `callback` as a parameter.

> [@marcantheunis](#):
>
> since i putted all beginAsync\_ex() result into the same var i will have created dangling interface references yes?  
> if so i need to hold some kind of list of them?  
> or can i simply ignore the interface result of the beginAsync\_ex call?  
> in fact do i need the interface reference at all?

if you don’t need to do anything with request (check state, cancel request, etc), you can just ignore result of `begin*` method like

```delphi
beginAsync_ex();
…
beginAsync_ex();
…
beginAsync_ex();

```

check `TClientForm.bUploadClick`:

```auto
procedure TClientForm.bUploadClick(Sender: TObject);
..
   GetService.BeginUploadPhoto(lFileName,lstr,Callback_UploadPhoto, lstr);
  end;
end;

```

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 9, 2024, 1:57pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/8 "2024-02-09T13:57:43Z")

</div>

so please some advice on the usage 🙂

let’s say i have a bulk of things to do, fetching a status of persons remotely  
this is a RO service

so i’m processing an list of 100 persons which i want to check using this async\_ex method

so a simple approach is to loop over this list and issue the beginAsync\_ex call  
i guess creating a TTask to execute that call is overhead

now i only have 1 callback procedure  
which will be executed threaded, so simultanious entries may occur  
if i’m using a thread safe list i guess i’m fine, so i can save the result back for the correct person (i’ll probably either store the IROAsyncRequest or use UserData to match the request with the correct list entry)

now here comes the question: what is the best way to detect the completion of all calls?  
in other words, at a certain moment i need to be able to detect if the bulk operation is finished…

any ideas on that?

tia,  
Marc

---

<div class="post-metadata">

### Author: ![mh](https://talk.remobjects.com/user_avatar/talk.remobjects.com/mh/32/18050_2.png) [@mh](https://talk.remobjects.com/u/mh)
#### Post date: [February 9, 2024, 2:00pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/9 "2024-02-09T14:00:36Z")

</div>

> [@marcantheunis](#):
>
> consider this:  
> var intf : IROAsyncRequest
> 
> intf := beginAsync\_ex();  
> …  
> intf := beginAsync\_ex();  
> …  
> intf := beginAsync\_ex();  
> …
> 
> so now i have 3 requests stored in same var intf…

No you don’t, you have the last of three requests stored in the `into` var. this isn’t quantum computing 😉

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 9, 2024, 2:07pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/10 "2024-02-09T14:07:35Z")

</div>

lol  
no no, that wat about something else, dangling interface references

so more like a threadlist of personstatus objs  
that personstatus class had a IROAsyncRequest member in which i could store the reference

and in the callback i could check aRequest matching that personstatus member

main issue is how to detect if all calls completed (or did not for that matter)

i could loop over that list keeping track of a response for each entry but then again if a call for some reason whatsoever does not result in a callback i will not know about it and wait…

unless the RO infrastructure has an internal timeout which would do the trick?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [February 9, 2024, 2:45pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/11 "2024-02-09T14:45:37Z")

</div>

Hi,

> [@marcantheunis](#):
>
> main issue is how to detect if all calls completed (or did not for that matter)

You can have some Integer value so you can do AtomicIncrement/AtomicDecrement when request is started and callback is called.

if you need possibility to cancel requests, better to store them in TInterfaceList.

You can check status of request with `Done` and `Cencelled` proeprties.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 9, 2024, 2:48pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/12 "2024-02-09T14:48:08Z")

</div>

ok and i can be sure that if i make 100 calls i will get 100 callbacks?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [February 9, 2024, 2:54pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/13 "2024-02-09T14:54:34Z")

</div>

Hi,

yes.  
you can examine code of `TROAsyncProxyThread2.IntExecute`.

Note: inside your callback you have to check `Cancelled` and `Done` properties like

```delphi
if not aRequest.Cancelled and aRequest.Done then ...

```

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 9, 2024, 3:14pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/14 "2024-02-09T15:14:34Z")

</div>

ok, didn’t check that…  
so aRequest.Cancelled is when there was a problem along the way i guess?  
and what is the meaning of aRequest.Done?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [February 9, 2024, 3:26pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/15 "2024-02-09T15:26:09Z")

</div>

Hi,

`aRequest.Cancelled` is set when user called `aRequest.Cancel` manually.  
`aRequest.Done` - request is finished - status can be good or bad.

Note: `End*` method can raise exception if exception was caught during execution of request.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 10, 2024, 6:44am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/16 "2024-02-10T06:44:06Z")

</div>

Last q: is there any chance that Done is false in the callback?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [February 12, 2024, 8:05am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/17 "2024-02-12T08:05:13Z")

</div>

Hi,

`Done` will be **true** in callback method.  
You can check this property when you have `IROAsyncRequest` instance.

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 12, 2024, 8:05am UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/18 "2024-02-12T08:05:41Z")

</div>

that’s what I expected, thx!

---

<div class="post-metadata">

### Author: ![marcantheunis](https://talk.remobjects.com/letter_avatar_proxy/v4/letter/m/bcef8e/32.png) [@marcantheunis](https://talk.remobjects.com/u/marcantheunis)
#### Post date: [February 12, 2024, 1:39pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/19 "2024-02-12T13:39:10Z")

</div>

but just to be sure:  
in the callback method:  
.Cancelled is always False right? (except when I trigger .Cancel)  
.Done is always true?

problem is that it seems that when the service is not running, i do get the callback with .cancelled false and .done true, leading me to conclude that the .beginxxx method succeeded but in fact it didn’t cause there was no endpoint…

what is a solid way to determine failure of the service side in the client?

---

<div class="post-metadata">

### Author: ![EvgenyK](https://talk.remobjects.com/user_avatar/talk.remobjects.com/evgenyk/32/16_2.png) [@EvgenyK](https://talk.remobjects.com/u/EvgenyK)
#### Post date: [February 12, 2024, 1:48pm UTC](https://talk.remobjects.com/t/async-ex-service-functions/27616/20 "2024-02-12T13:48:10Z")

</div>

Hi,

> [@marcantheunis](#):
>
> in the callback method:  
> .Cancelled is always False right? (except when I trigger .Cancel)  
> .Done is always true?

yep.

> [@marcantheunis](#):
>
> problem is that it seems that when the service is not running, i do get the callback with .cancelled false and .done true, leading me to conclude that the .beginxxx method succeeded but in fact it didn’t cause there was no endpoint…
> 
> what is a solid way to determine failure of the service side in the client?

have you called `End*` method inside of your callback ?

if failure was happened, calling of `End*` method will raise correspondent exception

[Next page](https://talk.remobjects.com/t/async-ex-service-functions/27616.md?page=2)
