Client CPU goes almost 100% when stop service - wcf

We have a service which is hosted as a Windows service. netTcpBinding with message security type without reliable session.
On the client side we have a proxy collection cached in a list as channel creation and dispose is costly operations. My client is connecting to server and getting the data from server.
Now if I stop the server, then the CPU jumps up. The worker thread which consumes CPU is for the code execution of
void System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, NativeOverlapped *)
When i dispose all the proxies the client application CPU consumption becomes none. I need to know how we can fix up this issue on the WCF.

One question is why are you having collection of proxy's on client for single wcf service. Say you have 20 proxies and WCF Service instancing is per-session then it will create 20 instances of service on your server each having memory allocated to it. If you are having per-call (which is default) then you will have even more instances. Instead of having list of proxies cant you reuse one proxy.
I suppose when you are stopping service, cpu has to clean(garbage collect) too many instances of service in short time hence it jumps.
Unless you do not close proxies their respective instances on server wont be released.Try making instancing Singleton.

Related

Should I Open and Close my WCF client after each service call?

I have developed a WCF service for consumption within the organization's Ethernet.
The service is currently hosted on a windows-service and is using net.tcp binding.
There are 2 operation contracts defined in the service.
The client connecting to this service is a long running windows desktop application.
Employees(>30,000) usually have this client running throughout the week from Monday morning to Friday evening straight.
During this lifetime there might be a number of calls to the wcf service in question depending on a certain user action on the main desktop client.
Let us just say 1 in every 3 actions on the main desktop application would
trigger a call to our service.
Now we are planning to deploy this window service on each employee's desktop
I am also using `autofac` as the dependency resolver container.
My WCF service instance context is `PerSession`, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using `autofac` container.
Now am not changing the `InstanceContext` attribute on the service implementation
because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to `Open` and `Close` the proxy for each call but if I leave the service to be PerSession it will create a new service instance for each call, which might not be required given the service and client have a 1-1 mapping. Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
So which approach should I take, make the service `Singleton` and Open Close for each call or
Open the client-side proxy when the desktop application loads/first service call and then Close it only when the desktop application is closed ?
My WCF service instance context is PerSession, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using autofac container
Generally you want to avoid sharing a WCF client proxy because if it faults it becomes difficult to push (or in your case reinject) a new WCF to those parts of the code sharing the proxy. It is better to create a proxy per actor.
Now am not changing the InstanceContext attribute on the service implementation because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session
I think there may be some confusion here. The InstanceContext.PerSession means that a server instance is created per WCF client proxy. That means one service instance each time you new MyClientProxy() even if you share it with 10 other objects being injected with the proxy singleton. This is irrespective of how you host it.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to Open and Close the proxy for each call
Incorrect. For a PerSession service that is very expensive. There is measurable cost in establishing the link to the service not to mention the overhead of creating the factories. PerSession services are per-session for a reason, it implies that the service is to maintain state between calls. For example in my PerSession services, I like to establish an expensive DB connection in the constructor that can then be utilised very quickly in later service calls. Opening/closing in this example essentially means that a new service instance is created together with a new DB connection. Slow!
Plus sharing a client proxy that is injected elsewhere sort of defeats the purpose of an injected proxy anyway. Not to mention closing it in one thread will cause a potential fault in another thread. Again note that I dislike the idea of shared proxies.
Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
Yes, like I said if you are going to inject then you should not call open/close. Then again you should not share in a multi-threaded environment.
So which approach should I take
Follow these guidelines
Singleton? PerCall? PerSession? That entirely depends on the nature of your service. Does it share state between method calls? Make it PerSession otherwise you could use PerCall. Don't want to create a new service instance more than once and you want to optionally share globals/singletons between method calls? Make it a Singleton
Rather than inject a shared concrete instance of the WCF client proxy, instead inject a mechanism (a factory) that when called allows each recipient to create their own WCF client proxy when required.
Do not call open/close after each call, that will hurt performance regardless of service instance mode. Even if your service is essentially compute only, repeated open/close for each method call on a Singleton service is still slow due to the start-up costs of the client proxy
Dispose the client proxy ASAP when no longer required. PerSession service instances remain on the server eating up valuable resources throughout the lifetime of the client proxy or until timeout (whichever occurs sooner).
If your service is localmachine, then you consider the NetNamedPipeBinding for it runs in Kernel mode; does not use the Network Redirector and is faster than TCP. Later when you deploy a remote service, add the TCP binding
I recommend this awesome WCF tome

WCF Web Service with a Singleton COBOL VM

I have a WCF Web Service that has no concurrency configuration in the web.config, so I believe it is running as the default as persession. In the service, it uses a COBOL Virtual Machine to execute code that pulls data from COBOL Vision files. Per the developer of the COBOL VM, it is a singleton.
When more than one person accesses the service at a time, I'll get periodic crashes of the web service. What I believe is happening is that as one process is executing another separate process comes in at about the same time. The first process ends and closes the VM down through normal closing procedures. The second process is still executing and attempting to read/write data, but the VM was shutdown and it crashes. In the constructor for the web service, an instance of the VM is created and when a series of methods complete, the service is cleaned up and the VM closed out.
I have been reading up on Singleton concurrency in WCF web services and thinking I might need to switch to this instead. This way I can open the COBOL VM and keep it alive forever and eliminate my code shutting down the VM in my methods. The only data I need to share between requests is the status of the COBOL VM.
My alternative I'm thinking of is creating a server process that manages opening the VM and keeping it alive and allowing the web service to make read/write requests through that process instead.
Does this sound like the right path? I'm basically looking for a way to keep the Virtual Machine alive in a WCF web service situation and just keep executing code against it. The COBOL VM system sends me back locking information on the read/writes which I can use to handle retries or waits against.
Thanks,
Martin
The web service is now marked as:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
From what I understand, this only allows a single thread to run through the web service at a time. Other requests are queued until the first completes. This was a quick fix that works in my situation because my web service doesn't require high concurrency. There are never more than a handful of requests coming in at a time.

What happens when I close/abort a WCF channel/proxy?

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).

WCF memory usage

I have a WCF service hosting in IIS using net.tcp binding and configured for PerCall instancing. For test purposes, I have a single operation that does absolutely nothing.
Every time a client connects and calls the operation, memory usage increases for the w3wp.exe process and after the client has closes the connection, the memory usage does not decrease. After repeated calls, the memory has increased from an initial 20MB to 500MB or more.
Is this normal behavior?
When you call a service with PerCall Instance Context mode then the memory should be released after the method returns. Since that is not happening in your scenario, try to implement the IDisposable interface on your services to be able to control the disposal of your services explicitly. Also make sure that you close your proxy connections on the client right after usage.

WCF Self-hosted service, client clean-up on service stop

I'm curious to know how I would go about setting up my service to stop cleanly on the server the service will be installed on. For example when I have many clients connecting and doing operations every minute and I want to shut-down the service for maintenance, how can I do this in the "OnStop" event of the service to then let the main service host to deny any new client connections and let the current connections finish before it actually shuts down its services to the client, this will ensure data isn't corrupted on the server as the server shuts down.
Right now I'm not setup as a singleton because I need scalability in the service. So I would have to somehow get my service host to do this independently of knowing how many instances are created of the service class.
You just have to call Dispose on the ServiceHost instance that you create. Once you do that, you will not accept any more clients and the service will continue to finish the operations for clients that are already connected.
I've been wondering the same thing. I found this article which has a pretty in-depth description of how to properly Close/Dispose as ServiceHost or Client.
http://www.danrigsby.com/blog/index.php/2008/02/26/dont-wrap-wcf-service-hosts-or-clients-in-a-using-statement/
In order to accomplish this. I had to create a service reference of itself and in the Windows Service OnStop initiate a new connection and change values in the WCF Service to "shut down" (this was just a shared boolean that the service was online or offline) the service so new clients wouldn't be able to connect (A function the client would call to see if the server was online or offline) and the existing connections would have time to finish up, then after all clients disconnect, continue to shut down the WCF Service using the .Close method.