Freigeben über


Wondering about WCF Proxy usage

Usually one of the topics in the WCF space that causes the most doubts and discussions are around WCF Proxy creation and usage.

I can say from my experience that most of time the doubts and discussion are based mostly one some confusion around how a WCF Proxy works, and oddly enough those are around using a WCF Proxy on a Singleton scenario.

One of the most recurrent question I got around this topic is always something like the following.

If I do not close my Singleton proxy object after making service call, would this have an impact on server load in terms of too many open connections? And (wait for it) if yes, how this concerns could be addressed while still leveraging performance gains derived from not creating proxy for every request.

That's just great, right? We always want to getting away with everything.

So, lets start by pointing to some background references on the web that could help here, so we do not go for a path of rephrasing knowledge that is already there.

In terms of WCF Client Proxy creation best practices we can always go to the Wenlong post around this topic, you can find it here.

If I was asked for a a straight answer on this, I would say that it is not advisable to leave proxies open as discussed here. Just bear in mind that even if you closing it, you are always getting the benefit of WCF implicit proxy caching (please refer ‘Best Practices’ in Wenlong post referred above).

However, going through "Best Practices" section in same link, we can see that reusing the same proxy is first in list, so keeping proxy open if client application intend to reuse is being seen as acceptable and even as a good thing.

We need to understand though, that this needs to be tested and you always need to considering the need to implement a throttling behavior on the Service (and any other adjustments made accordingly) to avoid server side bottlenecks.

On client side, there are also other considerations, like for example the number of concurrent connections allowed, this is governed by DefaultConnectionLimit property (defaults to 2) which would be relevant to avoid client side bottlenecks. This can be either controlled programmatically or through configuration with "ConnectionManagement".

Here enters another usual source of confusing, what this "MaxConcurrentCalls" and "MaxConnections" means and how to take advantage of them. 

Lets start by clarifying, "MaxConcurrentCalls" will be the number of max calls that can be executing at the same time on the Service, "MaxConnections" has to do with the total number of open connections on the service, regardless if the service is executing anything for the connection.

However, we need to know that there are indeed two types of "MaxConnections".

  • System.Net MaxConnections, it is relevant only on client side and signifies the allowed number of outgoing connections to a specific host.
  • netTcpBinding MaxConnections, these are relative to the number of pooled connections.

So in our WCF Proxy scenario, if a client opens a connection to the service, calls a method, and is waiting for the method to return, it will count against the "MaxConcurrentCalls".
As soon as the service returns a response to the client’s method call, it will not count against the "MaxConcurrentCalls" even if you didn’t close the client-side proxy.

Clear, right?

Finally, with this approach of not closing my Singleton WCF Proxy, we could ending up with a lot of connections opened on the IIS Server, could this been a serious issue on the IIS side?

The main point here will be that the service will be using ephemeral ports here and though configurable (they have a large default values on modern OSs), they do have a limit.

Please refer this post, around Ephemeral Port Limits to get a better understanding of this.

I would say that, for throttling in .NET 4 and above, the defaults should be good enough as they are defined accordingly with the processor count, but you are still free to modify them based on testing and fine tuning. This blog could be a starting point.

For connections, as I pointed out above, ephemeral ports are limited but depending on OS and configuration, you may have a huge range available.

So, concluding, keeping connections open for long time is ok and even advisable if we are constantly using them and if you are using "netTcpBinding", since it already uses inherent Connection Pool, you may be able to achieve same goal even with closing the proxy.

Hope that helps