Multiple method call using same client instance to WCF service - wcf

My WPF application is calling the WCF service using a single client object. This is working fine when request is sent and response is coming immediately before next request.
When I am sending the first request and it is taking 3 minutes to complete the calculation task and return the result. In the meanwhile second request is sent from my WPF application (ping request is sent every 3 second). At this time, I am getting the following error and WPF application getting disconnected:
The server did not provide a meaningful reply: this might be caused by a contract mismatch, a prematured session shutdown or an internal server error
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
My service behavior is written as follows:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults=true)]
I tried different combination and it is not working.

If you do multiple concurrent calls from singel client you should set ConcurrencyMode to Multiple in addition to InstanceContextMode ..
Note that if you set InstanceContextMode to Single, your service act as singleton, Then you should be aware of manipulating variables because it has reflection on other calls ..

Your Ping request should not use the same Channel. It should open it's own channel. Ideally, every independent request should open it's own channel (alternatively, you could build a queuing system). But accessing the same channel from two different threads is not going to work.

Related

WCF Service calling an external web service results in timeouts in heavy load environment

I have got the following scneario:
Our .NET client calls our WCF service - which in turn calls an external third party service to retrieve some data. Once the data is retrieved, our WCF service sets some values and then returns the control back to the client. The process of calling the external service has to be synchronous.
My problem is that this all works in a low load environment but when load gets high then we start queueing multiple requests, the WCF service starts timing out. We have set the "sendTimeout" property for the binding to 5 seconds and it times out after that.
I've tried replacing the external service with a mocked out local version and that handles the load OK but on the same hand the call to external service on it own is very quick - around 0.5 second. I can only presume that the timeouts are happening because too many requests were queued and WCF service couldn't respond within those allocated 5 seconds.
I have tried the following:
Set the values of maxConcurrentCalls, maxConcurrentSessions & maxConcurrentInstances to very high numbers
Set the value of system.net - connectionManagement - maxconnection to a very high number
Does any one have any ideas about what we can do in this scneario?
does your cpu peak during these high load times ? if not then you might be running out of threads. Make your wcf service that receives the original call asynchronous, and then call the external service asynchronously.
you will have to use asnyc pattern throughout your call chain to make sure nothing is blocking the thread.
http://msdn.microsoft.com/en-us/library/ms731177.aspx

callback invalid in wcf service

I have a win forms client that accesses a wcf service for a long running operation. The service exposes subscribe and unsubscribe methods. When a client calls the subscribe method, service generates new guid for it and gets the current callback context, saves this guid and callback context in a client Dictionary and returns the Guid. On user request, client call service with this guid to start the long operation. Once the service finishes the operation it gives a callback to the client. the client then retrieves the processed data from the service.
The error I get sometimes when doing a callback is
The operation 'OnServiceCallback' could not be completed because the sessionful channel timed out waiting to receive a message. To increase the timeout, either set the receiveTimeout property on the binding in your configuration file, or set the ReceiveTimeout property on the Binding directly.
The part that I am not able to understand is that this happens very inconsistently. Most of the times it happens after the client and the service have been running for some time.
I am a beginner in wcf service and welcome any suggestions to solve this error.
Binding has property called receiveTimeout. This property is by default set to 10 minutes. It defines how long does the service instance wait for next request before it is terminated. So if there is no activity between client and service within 10 minutes your service instance is closed and client can't use it any more. In duplex service it can be even more complicated because there are services on both sides. You will probably need to configure receiveTimeout on both ends.
I was able to figure the answer to the error by doing some good old trial and error. The callback was failing because the OperationContext.Current object that I was trying to use was null. This was because I was trying to access the OperationContext.Current object on a thread which was different from the service thread. So to solve that I am now accessing the OperationContext.Current object in the service thread and then passing the callbackContext as a parameter to the external processing logic which actually needs to use it.

How do I properly handle a faulted WCF connection?

In my client program, there is a WCF connection that is opened at startup and supposedly stays connected til shutdown. However, there is a chance that the server closes due to unforeseeable circumstances (imagine someone pulling the cable).
Since the client uses a lot of contract methods in a lot of places, I don't want to add a try/catch on every method call.
I've got 2 ideas for handling this issue:
Create a method that takes a delegate and executes the delegate inside a try/catch and returns an Exception in case of a known exception, or null else. The caller has to deal with nun-null results.
Listen to the Faulted event of the underlying CommunicationObject. But I don't see how I could handle the event except for displaying some error message and shutting down.
Are there some best practices for faulted WCF connection that exist for app lifetime?
If you do have both ends of the wire under your control - both the server and the client are .NET apps - you could think about this approach instead:
put all your service and data contracts into a shared assembly, that both the server and the client will use
create the ChannelFactory<IYourService> at startup time and cache it; since it needs to have access to the service contract, this only works if you can share the actual service contract between server and client. This operation is the expensive part of building the WCF client
ChannelFactory<IYourService> factory = new ChannelFactory<IYourService>();
create the actual communications channel between client and server each time you make a call, based on the ChannelFactory. This is pretty cheap and doesn't cost much time - and you can totally skip any thoughts about having to detect or deal with faulted channels.....
IYourService client = factory.CreateChannel();
client.CallYourServiceMethod();
Otherwise, what you basically need to do is wrap all service calls into a method, which will first check for a channel's faulted state, and if the client proxy is faulted, aborts the current one and re-creates a new one.
I wrote a blog post on exceptions in WCF that deals with how to handle this: http://jamescbender.com/bendersblog/Default.aspx

Why are my message be processed out of order over a single WCF TCP channel (with ConcurrencyMode.Reentrant)?

The client sends a lot of messages to the server from a single thread, over a single WCF channel.
The client sends the message with BeginMyMethod(x, b) as it does not wish to block while they get processed.
We have reliable messaging turned on, as we don’t wish to lose any messages, or have them get out of order.
However the messages are being despatched on multiple threads on the server, so are being process out of order.
We can’t have the server being single threaded, as we don’t wish a long running request from one client to block other clients.
So I just wish to process all the messages that come from a single client (over a single channel) in order with only one message from each cleint being processed at a time.
This would be easy for raw socket programming, however how to I get WCF to work as I wish?
I am now thinking that ConcurrencyMode.Reentrant does not behave well when used with InstanceContextMode.Single If I set use ConcurrencyMode.Single the messages are kept in order, but my call-backs deadlock.
(The test that gets the messages out of order has no callbacks and does not make any outgoing WCF calls, so I would expect ConcurrencyMode.Reentrant to behave the same as ConcurrencyMode.Single in that given test, but it does not)
I a not using any WCF config files, the code is:
serviceHost = new ServiceHost(this);
serviceHost.AddServiceEndpoint(
typeof(IAllEngineManagersAsyncCallbacks),
new NetTcpBinding(SecurityMode.None, true),
endPointAddress);
I have now worked round this problem by:
Changing all my call-backs from the server to the client to be OneWay
Using a dispatcher in the client before passing on any callback from the server, so client code never calls the sever from within a call-back
The client call-back object is marked with CallbackBehavior(UseSynchronizationContext=false, ConcurrencyMode=ConcurrencyMode.Single)
When running in Winform or WPF I use SynchronizationContext.Post to depatch the callbacks
When the cleint is a Console or a Windows server I use a custom depatcher.
So letting me use ConcurrencyMode.Single on both the server and the client.
It is now working as expected.
(BeginMyMethod(x, b) is still being used to send messaged from the client to the server)
(ConcurrencyMode.Reentrant seems to sometimes release the lock even when the WCF call is not made on the some thread that is processing the incoming message, it is just not a useful as Reentrant was in DCOM)
If you are using the generated BeginXXX async-methods, these are executed on a ThreadPool thread.
So although you've send the messages in a defined order, nobody guarantees you in which order the ThreadPool executes the requests.
I think that Reentrant mode implies that you allow messages be processed out of order. Normal behavior of such service would be: get message, put in queue for internal threads to process, and when it's done notify client about result. So maybe your service get messages in proper order but some of them are quiker to process and return earlier than others?

Long-running callback contract via WCF duplex channel - alternative design patterns?

I have a Windows service that logs speed readings from a radar gun to a database. In addition, I made the service a WCF server. I have a Forms and a CF client that subscribe to the service and get called back whenever there is a reading that satisfies certain criteria.
This works in principle, but after some time the channel times out. It seems that there are some fundamental issues with long-running connections (see
http://blogs.msdn.com/drnick/archive/2007/11/05/custom-transport-retry-logic.aspx) and a duplex HTTP callback may not be the right solution. Are there any other ways I can realize a publish/subscribe pattern with WCF?
Edit: Even with a 2 hour timeout the channel is eventually compromised. I get this error:
The operation 'SignalSpeedData' could not be completed because the sessionful channel timed out waiting to receive a message. To increase the timeout, either set the receiveTimeout property on the binding in your configuration file, or set the ReceiveTimeout property on the Binding directly.
This happened 15 minutes after the last successful call. I am wondering if instead of keeping the session open, it is possible to re-establish a fresh session for every call.
Reliable messaging will take care of your needs. The channel reestablishes itself if there is a problem. WSDualHTTPBinding provides this for the http binding, and there is also a tcp binding that allows this. If you are on the same computer, named pipe binding will provide this by default.