We have quite big SL project using WCF Ria Services and LinQtoSQL (not EF).
As we have more and more data we started to have performance issues.
We started to investigate. We took one query and try do track what is going on.
When we run query from SQL Managenent Studio it completes in time less than minute. But when this query is executed from our application it takes very long time to and some times it rises TimeOut Exception (Load operation failed for query 'xxx'. The HTTP request to 'http://localhost:1501/ClientBin/xxx.svc/binary/xxx' has exceeded the allotted timeout. The time allotted to this operation may have been a portion of a longer timeout.) We've set Timeout in SL application to 20 minutes and even such a long time is not enough.
What is interesting when we rebuild indexes in database, query called from SL application completes in time less than minute. But it is not a solution, because after few minutes problem returns (we would have to rebuild indexes every few minutes).
Query currently returns about 1700 rows. Is it to much to handle it efficiently in SL application?
Has anybody have similar problem? What we could do in such situation to improve performance?
Every suggestion will be appreciated.
I don't use Ria Services, but we have a SL app that returns 14,000+ records to the browser in a very timely manner. Haven't actually timed it, but it is just a few seconds. Maybe 3. So Silverlight/WCF isn't a bottleneck. At worst, maybe you can do this one part NOT in Ria Services.
Ok, I know we could do it another way. But it is not a sollution, after some time another query could start to cause problems.
And what about rebuilding indexes? Why after this operation everything works good, but only for a very short time. How rebuilding indexes could affect RIA and SL performance?
Do you have the possibility to run SQL Trace to capture the SQL being generated by RIA service? As you say, re-building an index is counter-intuitive as to having an effect unless the SQL generated is a bit odd, perhaps not running efficiently as far as the query optimiser is concerned. The other thing to check is the true execution time to make sure it is not another part of the process of returning the data, i.e. memory leak or such.
Yes I have possibility to run SQL Trace. As I wrote before we've identified the query causing the problem. Generated SQL looks awful, but it runs quick (when it is executed manually from Management Studio) and execution plan looks good. I don't see necessity to change it. Database was the first thing we've try to improve, but it looks like problem is somewhere else.
If you are sure that the SQL is still fast when you experience the performance problems, double check that the event handlers are being freed after use. If possible build the simplest of SL test apps to verify problem exists in generated code or not and perhaps profile the SL test app. Hope I'm not teaching your granny to suck eggs so to speak :)
You said you set timeout to 20 minutes. Did you set that in your web.config or your client config. Despite Microsoft documentation, apparently the proper place to set it is in the client config. (and they changed that over time and maybe IIS versions) sladapter here had some test program that she runs and she says it is definitely using the one in the client config. So you might want to check that.
Then there is a ReceiveTimeout value in the registry that I have read can be used too. I recently thought I had this problem, but it turned out the user did not have the value set at all, so that wasn't their problem. My registry was set to 10 seconds. I don't think that is the default, so you need to check your own at "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings". You can read about this here:
That is about all I can suggest.
Sorry for a delay in my activity, but I have a very busy week :(
Currently we have plan to try to migrate to SL5 and see how it works (currently we use SL4).
Thank you for your suggestions. I'm not sure if I understand what you mean saying to check that event handlers are freed after use.
Could you explain it more clearly? Maybe you could include some simple example.
We haven't build test app yet - it's hard to keep it simple to simulate the problem.
Timeout is set from code in OnCreated() method in context class. Setting it in web.config and in client config didn't make any effect. Now it is set properly and it works (tested).
Setting timeout in registry is not a good idea from my point of view. Application is accessed from many hosts and changing registry on all of them would be problematic if not impossible (security policy in our customers' companies).
I would remove what you did in the registry and use the client config. It DOES work there. I've done it and sladapter has some sort of test program and she determined that client config works.
HOW did you try it in client config? What did you put in there?
I didn't change anything in registry. Timeout is set from code in OnCreated() method in context class.
partial void OnCreated()
TimeSpan twentyMinutes = TimeSpan.FromMinutes(20);
public static void ChangeRiaSendTimeout(DomainContext ctx, TimeSpan timeout)
PropertyInfo channelFactoryProperty = ctx.DomainClient.GetType().GetProperty("ChannelFactory");
if (channelFactoryProperty == null)
throw new InvalidOperationException("There is no 'ChannelFactory' property on the DomainClient.");
ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(ctx.DomainClient, null);
factory.Endpoint.Binding.SendTimeout = timeout;
factory.Endpoint.Binding.ReceiveTimeout = timeout;
factory.Endpoint.Binding.OpenTimeout = timeout;
factory.Endpoint.Binding.CloseTimeout = timeout;
This is client side. And also in web.config in bindings section at server side. But this is not a problem here. It works.
The problem is that data which are returned from SQL Server in several seconds don't show in SL application even in 20 minutes.
Once again I would like to emphasize that setting timeout is not a problem here. We've set timeout successfully. And we know how to achieve it. We don't need help with setting timeouts. We need help with problem with long time of getting result to SL application while query on database server completes in few seconds. If somebody know how to help us please give us some advice.
As I said, we get 14,000+ records without problems. I don't remember doing anything special other than perhaps this in the web.config:
<bindings> <customBinding> <binding name="BinaryBasicHttpEndpointBinding" > <binaryMessageEncoding/> <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" /> </binding> </customBinding> </bindings>
Maybe that is something that makes performance improve.
If it doesn't, then my guess is your throughput is NOT limited by WCF, but something in your network.
Yes, we have also this parameter set in web.config. It helps with big messages size, but not with performance. We think that our problem could be caused by some issues with serialization/deserialization, but it's only our thought. What do you think about it?
We've tried to use basicHttpMessageEncoding and also binaryMessageEncoding. The problem exists independently :(
Now we're trying to migrate to SL5, but I don't believe it helps :(
Migration will take us some time. I'll let you know if it helps when we finish.