WCF Proxy client takes the time to create, any cache or singleton solution for it

We have more than dozon wcf services and are called using TCP bindings. There are many calls to the same wcf service in different places in the code.

AdminServiceClient client = FactoryS.AdminServiceClient (); // considerable time is required. and

client.GetSomeThing (param1); client.Close ();

I want to cache the client or produce it from singleton. so that I can save some time, is this possible?

thanks

+7
source share
2 answers

Yes it is possible. You can make the proxy object visible for the entire application or wrap it in a singleton class for accuracy (my preferred option). However, if you intend to reuse the proxy server for the service, you will have to handle channel errors.

First, create your singleton class / cache / global variable containing the proxy (or proxy) instance that you want to reuse.

When creating a proxy server, you need to subscribe to the Faulted event on the internal channel

proxyInstance.InnerChannel.Faulted += new EventHandler(ProxyFaulted); 

and then put some reconnect code inside the ProxyFaulted event handler. The Failure event will be triggered if the service crashes or the connection times out because it was inactive. An error event will only fire if you have a reliable binding in your binding in the configuration file (if this undefined value is included in netTcpBinding by default).

Change If you do not want your proxy channel to be open all the time, you will need to check the status of the channel before each use and recreate the proxy if it is faulty. Once the channel has worked, there is no way but to create a new one.

Edit2: The only real difference in the load between saving the channel and closing it each time is the keep-alive packet sent to the service, and is recognized so often every time (which is what is behind the channel failure event). With 100 users, I don't think this will be a problem.

Another option is to place your proxy creation inside the use block, where it will be closed / deleted at the end of the block (which is considered bad practice ). Closing a channel after a call may cause the application to freeze because the service has not yet completed processing. In fact, even if your service call was asynchronous or the service contract for the method was one-way, the channel closure code will be blocked until the service is completed.

Here is a simple singleton class that should have unfilled bones of what you need:

 public static class SingletonProxy { private CupidClientServiceClient proxyInstance = null; public CupidClientServiceClient ProxyInstance { get { if (proxyInstance == null) { AttemptToConnect(); } return this.proxyInstance; } } private void ProxyChannelFaulted(object sender, EventArgs e) { bool connected = false; while (!connected) { // you may want to put timer code around this, or // other code to limit the number of retrys if // the connection keeps failing AttemptToConnect(); } } public bool AttemptToConnect() { // this whole process needs to be thread safe lock (proxyInstance) { try { if (proxyInstance != null) { // deregister the event handler from the old instance proxyInstance.InnerChannel.Faulted -= new EventHandler(ProxyChannelFaulted); } //(re)create the instance proxyInstance = new CupidClientServiceClient(); // always open the connection proxyInstance.Open(); // add the event handler for the new instance // the client faulted is needed to be inserted here (after the open) // because we don't want the service instance to keep faulting (throwing faulted event) // as soon as the open function call. proxyInstance.InnerChannel.Faulted += new EventHandler(ProxyChannelFaulted); return true; } catch (EndpointNotFoundException) { // do something here (log, show user message etc.) return false; } catch (TimeoutException) { // do something here (log, show user message etc.) return false; } } } } 

Hope this helps :)

+8
source

In my experience, creating / closing a channel based on each call results in very little overhead. Take a look at https://stackoverflow.com/a/318628/ This is not a Singleton question per se, but related to your problem. Usually you do not want to leave the channel open after you are done with it.

I would recommend that you use a reusable ChannelFactory implementation if you haven't already done so, and see if you have any performance issues.

+2
source

All Articles