Should I bother with disposing (using close() and abort() on exception) the WCF proxy generated using ClientBase when I am using WebHttpBinding? Since its POX/ REST over http, I am wondering if there is any harm in leaving the proxy alone after the service call!?
Technically if it's not a sessionful binding (which webHttpBinding is not), it's less important, but you'd potentially be wasting resources if you were creating clients in a tight loop (eg, faster than the GC got around to cleaning them up and releasing the connections). HTTP connections are pooled and shared by the ConnectionPointManager though, so you'd probably be OK on that front.
Still, it's not a great idea to rely on those implementation details, because if something changes down the road, you'll wonder why your client performance starts to suck. I'd clean up...
Related
During migration of a set of old applications from Remoting to WCF I'm struggling with a good way of lifetime handling for the WCF proxies.
Initially I kept the same pattern I had with Remoting: Create a proxy server object during application startup and use it as long as the application is running.
This pattern had 2 problems, though:
When any call during the runtime of the application failed and the server threw an exception, the client proxy would move to Faulted state and was no longer usable. I fixed this by adding an ErrorHandler on the server side and only throwing FaultExceptions.
With infrequent server calls, the proxy channel would timeout after some time and you only notice when the next call fails. Increasing the Send/ReceiveTimeout to very long timespans is a no-go, from what I read.
This article suggested creating a new proxy for every call and caching the ChannelFactory.
While this solved both problems, it also killed performance.
Caching the ChannelFactory was a good idea, but in contrast to what the article above said, creating the proxy is far from light-weight.
Well, creating the proxy itself is fast, but opening the Channel (what has to be done when calling the server) is incredible slow.
I've been using a plain vanilla net.tcp channel and each server call took about 2 seconds (in contrast to a few ms if re-using the proxy).
Because it's a large code base I don't want to go through each and every server call and check the lifetime requirements for each block of calls.
Now I'm unsure which way to go. Any advice?
Thanks in advance,mav
It there any disadvantage of creating a wcf client in code everytime a call is needed. currently i have a static class that creates a client and reuses it for a period of time (couple of minutes before the wcf service times out)
i'm having problems with it getting into a faulted state while i'm in development because i keep recompiling the WCF code. its an annoyance now but think it'll be fine in production.
but... creating client proxy with user creds everytime a call is made... bad practice? performance issues?
As far as I know there is no performance penalty and this is the good way of doing it i.e create a client proxy each time you need it.
And each time you're done with it, it is a recommended best practice to always close the proxy. Closing the proxy releases the connection held toward the service, which is particularly important to do in the presence of a transport session. It also helps ensure the threshold for the maximum number of connections on the client’s machine is not reached. Closing the proxy terminates the session with the service instance.
I think the best answer is a little of both.
there is definitely a performance hit creating a proxy client every call. if you can create a proxy client and use it for all the calls you're going to make immediately. then dispose of it. it is much faster.
Is it really worth pooling WCF proxy clients, or is it better to instanciate a new proxy on every call to a given method?
By the way, does anyone have a pooling pattern for this kind of proxies which he/she is willing to share?
It is worth to cache ChannelFactory because its construction is costly. Proxies generated by Add Service Reference (or svcutil.exe directly) do this in some scenarios (generally you must not build binding in code if you want to have this caching). If you build ChannelFactory manually (you don't use generated proxies) it is up to you to store it somewhere instead of initializing it every time you need it.
Pooling proxies probably doesn't make much sense. For stateless services the proxy creation should be fast (if you have cached factory). For statefull services you don't want sharing proxy among multiple "clients". There is also pooling on connection level itself. HTTP bindings use something called persistent connections by default. These connections can be reused by multiple proxies. Net.tcp and net.pipe bindings use connection pooling internally. It means that lifetime of the proxy doesn't have to be the same as lifetime of the connection.
I'm trying to get a better understanding of what's going on when I use a WCF proxy. I'm having trouble understanding what happens when I close (or don't close) a proxy.
What's going on when I call Close() or Abort() on a WCF proxy? What's the difference?
How does it differ between types of bindings (like, a sessionless BasicHttpBinding vs. something sessionful)?
Why can Close() throw in certain situations and why can it be a blocking operation?
Closing WCF client
A client has an inherited responsibility of gracefully closing the connection. It is always recommended to close a proxy client. If the binding between a client and a service is transport-layer sessionful, then closing a proxy is essential to tear down the connection between both parties. Service has a payload threshold defined for concurrent connections. If the number of concurrent connections goes above this threshold linearly then the overall service performance decreases exponentially. This is why it is crucial to dispose of the connection as soon as possible. Closing the proxy also notifies the service instance that it is no longer in use and may be collected by GC (subject to service instance management). If the client does not close a connection, it is still automatically torn down by WCF timeouts (found in the configuration files).
Aborting WCF client
In the situation where there is a fault in the service-client interaction, the objects on both ends are potentially totally broken. Thus using a proxy after the exception is not advised. Given the WCF binding use transport sessions, the client after a fault would not even be able to close it (if there was no transport layer session then the client could use or close the proxy, but this is not recommended as the configuration of sessions could change). So after a fault has happened the only safe operation is to abort a proxy.
Close is a synchronous operation, it can throw if the transport session has been damaged by a fault and it is a blocking operation until a confirmatory response from service is received (true for some bindings).
I'm stuck with a bit of an annoying problem right now.
I've got a Silverlight 4 application (which runs OOB by default). It uses WCF with net.tcp as means of communicating with the server.
The client uses a central instance of the wcf client proxy. As long as everything keeps running on the server side, everything's fine.
If i kill the server in the middle of everything, i drown in an avalanche of exceptions on the client side (connection lost, channel faulted etc etc).
Now i'm looking for a way to handle this in a clean and centralized way (if centralized is possible).
The SL app has one central client object sitting in App.cs (public static MyClient Client { get;set;}), which gets initialized on application start.
Any idea how to properly handle any connectivity problems on the client object?
You mention that you're using a central instance of the WCF client proxy.
If this is the case, then when a server error occurs, the proxy will go into the Faulted state. To keep things centralized, you could cast the client proxy to an ICommuicationObject and attach an event handler to the Faulted event which replaces the faulted proxy, with a new proxy when the event fires.
The usual warnings about thread-safety for centralized access to resources apply!
I think i found a workable - though not centralized - solution. Instead of cluttering the code with try/catch blocks, all it seems to need is a null-check for the event.Error property. If something happened to the connection, this property is always not null. The exceptions only get raised if you try to access event.Result.
It may not be the most beautiful solution, but it appears to work so far.
Perhaps there is a more elegant way though...