I have a quite large "old" WCF Service with many different methods.
The most of these methods are "normal" so they should answer in less than 10 seconds but there are several methods (8 or 9) that are long processes so they can take a long time to get a response.
The receivetimeout and sendtimeout were set to 00:40:00 to ensure they had time enought to accomplish these processes.
The problem is sometimes we have connection issues and the "normal" methods take a really long time to crash...
They are all in the same service because they use a really big model and they wanted to reuse the model from the service in every call (not having a PersonsService.User and a RobotsService.User... because they are the same class in different services).
The first solution I imagine is to make a different Service with those long processes and set a short timeout to the normal service... but I should have to make a lot of changes because of Model use...
Is there any way to set a different timeout in each call? Or by service method? Should I chunk the Service anyway?
Thanks in advance!!
First of all, the timeout to configure in your case is OperationTimeout, which allows the time limit to wait for the service to reply before timing out. You can modify the operation timeout before making a call from the client side.
To set the OperationTimeout on the channel, you can type case your proxy/channel instance as IContextChannel and set OperationTimeout.
For example:
IClientChannel contextChannel = channel as IClientChannel;
contextChannel.OperationTimeout = TimeSpan.FromMinutes(10);
HTH,
Amit
Related
I have a system, that request data from a WCF webservice
it is like so:
WCF1 calls WCF2, WCF2 calls WCF3 and WCF3 do its job and returns response
My problem here is some of the operations takes a long time "about 2 min" to process
So if WCF1 send a request that takes long of time, and then another request from WCF1 that should take a second, it will wait until the first request finishes
i read about the problem, some of users said to use
<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.PerCall)> _
this doesn't solve the problem 100%
Can u please advice
I do not think those settings will solve your problem.
From the source:
In PerCall instancing, concurrency is not relevant, because each
message is processed by a new InstanceContext and, therefore, never
more than one thread is active in the InstanceContext.
Bottom line, because you are using PerCall activation, there is no point in adding the ConcurrencyMode.Multiple as each incoming request will get its own instance of the service class to handle its request.
You should try to narrow down what is really causing the performance problem. Look at the underlying code that your WCF services are calling.
EDIT
From another SO post.
In terms of behavior: ConcurrencyMode does not matter for a PerCall
service instance.
In terms of performance: A PerCall service that is
ConcurrencyMode.Multiple should be slightly faster because its not
creating and acquiring the (unneeded) thread lock that
ConcurrencyMode.Single is using.
Is it possible to determine the client timeout values on the server? I am in the unfortunate position that I have a long running WCF service (about 90 seconds) and I would like to know beforehand if the client is going to time out.
Any ideas?
Unless you force the client to tell you what his timeout is, you have no way of knowing that.
You could kindly ask for the information, adding a method parameter, or header.
You could also try to break your long running call into smaller parts, forcing the client to make subsequent calls if your business allows.
You could use asynchronous calls with a callback, one way method / duplex channels.
There are other possibilities, but we need to know more about your environment.
Assume a WCF service with ServiceBehavior.ConcurrencyMode = Single.
When exactly does the service start blocking for concurrent calls?
For example, say we have two clients: Slow and Fast.
At time 0 Slow starts a slow service call that includes a huge chunk of data.
At time 1 Fast makes a fast service call.
At time 2 the slow data finally arrives and the service code is executed on the server.
Assuming buffers configured in WCF to be larger than the huge chunk, which call will get executed first?
In other words, does blocking start when all call data has been received at the server side or when the client initiates the call?
Is the service blocked during the data transfer or only during code execution?
Unless you configure InstanceContextMode to Single as well both calls will be executed concurrently. So suppose that you have InstanceContextMode set to Single.
I didn't test it but I would expect such behavior. Concurrency mode is service behavior so it takes place once the service instance / instance context is resolved. In buffered mode that happens after whole message is received in streaming mode it should happen after message headers are received. So in case of buffered transport I would expect that fast client will be processed first and in case of streamed transport it depends if message headers from slow client was already received.
But as I wrote before this is only my expectation.
I'm using perfmon to examine my service behaviour. What I do is I launch 6 instances of client application on separate machines and send requests to server in 120 threads (20threads per client application).
I have examined counters and maximum number of instances (I use PerSession model and set number of instances to 100) is 12, what I consider strange as my response times from service revolve around 120 seconds... I thought that increasing number of instances will cause WCF to create more instances, and as a result response times would be quicker.
Any idea why WCF doesn't create even more instances of service?
Thanks Pawel
WCF services are throttled by default - it's a service behavior, which you can tweak easily.
See the MSDN docs on ServiceThrottling.
Here are the defaults:
<serviceThrottling
maxConcurrentCalls="16"
maxConcurrentInstances="Int.MaxValue"
maxConcurrentSessions="10" />
With these settings, you can easily control how many sessions or concurrent calls can be handled, and you can make sure your server isn't overwhelmed by (fraudulent) requests and brought to its knees.
Ufff, last attempt to understand that silly WCF.
What I did now is:
create client that starts 20 threads, every thread sends requests to service in a loop. Performance counter on server claims that only 2 instances of service object are created all the time. Average request time is about 40seconds (I start measuring before proxy call and finish after call returns).
modify that client to start 5 threads and launch 4 instances of that client (to simulate 20 threads behaviour from previous example). Performance monitor shows that 8 instances of service object are created all the time. Average request time is 20seconds.
Could somebody tell me what is going on? I thought that there is a problem with server that it doesn't want to handle more requests at concurently, but apparently it is client that causes a stir and don't want to send more requests concurently... Maybe there is some kind of configuration option that limits client from sending more then two requests at one time... (buffer,throttling etc...)
Channel factory is created in every thread.
You might want to refer to this article and make adjustment to your WCF configuration (specifically maxConnections) to get the number of connections you want.
Consider using something like http://www.codeplex.com/WCFLoadTest to hit the service.
Also, perfmon will only get you so far. If you want to debug WCF service you should look at the SvcTraceViewer and SvcConfigEditor in the Windows SDK.
On your service binding what have you set the maxconnections to? Calls to connect will block once the limit is reached.
Default is 10 I think.
http://msdn.microsoft.com/en-us/library/ms731379.aspx
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.