Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I ignore WCF asynchronous EndXXX call?

I have 2 services servicing WCF calls. From a client I send the same asynchronous WCF BeginXXX call to both services and then start waiting for replies with a WaitHandle.WaitAny(waitHandles) where waitHandles is an array of WaitHandles from the IAsyncResults returned by the 2 BeginXXX calls.

I want to use only the reply from the service that answers faster, i.e. when WaitHandle.WaitAny returns with an index I only call EndXXX with the corresponding IAsyncResult to get the faster result. I don't ever call the other EndXXX.

My reason for doing this is that sometimes a service uses several seconds in garbage collection and is not able to answer fast. According to my experiences the 2 services do garbage collections usually in different times so one of them is almost always capable of returning a fast answer. My client application is very time critical, I need an answer within a few milliseconds.

My questions are:

  1. Can I safely ignore calling EndXXX method for the other service that was slower in answering? I am not interested in the slower result but want to use the faster result ASAP. According to my experiments nothing bad seems to happen even if I don't call the EndXXX method for the corresponding slower BeginXXX async result.

  2. Would somebody mind explaining to me what exactly happens when I don't make an EndXXX call for a corresponding BeginXXX? Under debugger in Visual Studio I seem to able to see that another answer is processed in the .NET framework via an I/O completion port and this processing does not originate from my client calling EndXXX. And I don't seem to have any memory leaks because of not making the EndXXX call. I presume all objects involved are garbage collected.

  3. Does it make any difference whether the server side method XXX implementation is a single synchronous XXX or an explicit asynchronous BeginXXX/EndXXX pair?

  4. IMHO a synchronous XXX method implementation will always return an answer that needs to be handled somewhere. Does it happen on client or server side in my case when I fail to call EndXXX?

  5. Is using the WaitHandles a good and most efficient way of waiting for the fastest result?

  6. If I have to call EndXXX for each BeginXXX I have sent out makes things quite awkward. I would have to delegate the uninteresting EndXXX call into another thread that would just ignore the results. Calling all EndXXX calls in my original thread would defeat the purpose of getting hold of and using the faster answer in a synchronous manner.

like image 786
aku Avatar asked Mar 21 '14 17:03

aku


1 Answers

  1. The documentation says that you have to call the end method. If you violate what the docs demand you are in undefined behavior land. Resources can leak. Maybe they just do so under load, who knows?
  2. I don't know, sorry. I'm giving a partial answer. My suggestion: Implement a service method that does nothing and invoke it 10M times in a loop. Do resources leak? If yes, you have your answer.
  3. No, Server and client are independent. The server can be sync, the client async or vice versa. Both cannot even tell the difference of what the other does. The two services are separated by TCP and a well-defined protocol. It is impossible for a client to even know what the server does. The server does not even have to use .NET.
  4. I'm not sure what you're asking. Under the hood, WCF clients use TCP. Incoming data will be handled "somewhere" (in practice on the thread-pool).
  5. If your code is fundamentally synchronous, this is the best you can do. You'll burn one thread waiting for N asynchronous service calls. That's ok.
  6. Why don't you just specify a callback in BeginXXX that does nothing else but call EndXXX? That way you always call EndXXX and conform to how the framework is meant to be used. You can still use wait handles.
like image 146
usr Avatar answered Sep 27 '22 23:09

usr