D.Tkalcec (RTC)
|
|
« Reply #1 on: March 09, 2010, 07:20:35 PM » |
|
Here is a short explanation of the "DoWaitForCompletion" method, as it is written in the RTC SDK Help file and method comments (source code):
"Wait for all posted requests and function calls to complete, be aborted, be calceled, or for the connection to close."
It may not be obvious from the above sentence, but "all posted requests" does not only mean requests which have been posted before the DoWaitForCompletion method was called, but also any requests posted while waiting for a response (or responses) from other, previously posted requests.
In other words, if a new request gets posted while DoWaitForCompletion is waiting for a response, then DoWaitForCompletion will not return until the last posted requests was sent and its response received.
If that does not explain what you are doing wrong, let me go through your example and try to explain it:
1) You expect the Client to be blocking, but you have left the "Blocking" property of your TRtcHttpClient component at its default value = FALSE. And this means your Client is per definition NON-BLOCKING. Would you have set the "Blocking" property to TRUE, even with your rather strange example, the results would be what you thought they should be. In other words, each of your blocking remote function calls would give you the Result received from that specific remote function, even if another function was posted while waiting for the result from the Server.
2) You have created a background thread from which you are posting messages to the main thread, from where you are using the exact same TRtcHttpClient and TRtcClientModule component to post more remote function calls into the request queue. Because you are using a message-driven asynchronous WinSock implementation (which you are doing when Blocking=FALSE, useProxy=FALSE and useWinHTTP=FALSE on your TRtcHttpClient component), DoWaitForCompletion will have to process the message posted from your background thread even if you would call Execute with "AllowMessageProcessing=FALSE".
Hence, the message you are posting from your background thread is adding more remote function calls to the queue and DoWaitForCompletion will need to wait until the last one has been completed before returning. And because a single TRtcClientModule only has a single internal TRtcResult object for use with the blocking Execute method (it is supposed to be used in BLOCKING mode, so a single result is all it needs when used correctly, as there will always be only one call at a time), if you use Execute to call additional remote functions while waiting for the result on the last Execute call, all your Execute methods will return the same result. The result received from the last Execute call. And that is exactly what you see in your example. Your result from Execute made in Call1 is being overridden with the result received from Execute made in Call2.
3) To make things even worse, you are using the non-blocking Sockets implementation (TRtcHttpClient.Blocking=FALSE,useProxy=FALSE, useWinHTTP=FALSE and useSSL=FALSE) with the "Execute" method called with "AllowMessageProcessing=TRUE". Without disabling any buttons or forms, this will allow your client application user to click any buttons *again* while you are still waiting for the result of your last posted remote function call, thus giving your user the ability to to post multiple remote function calls to the Server while still waiting for the 1st result to arrive - even without using background threads.
If your remote function calls are mostly blocking, I would recommend you to set the "Blocking" property of your TRtcHttpClient component to TRUE. This will make your implementation a lot easier to maintain. If your remote function calls are mostly non-blocking and you want to use events to get and process the results instead of using the blocking Execute method, make sure your client will know what to do with received results.
I hope this explains your problem. If you have more questions, feel free to ask.
Best Regards, Danijel Tkalcec
|