none
WCF RIA Services performance issues

    Question

  • Hello,

    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.

    Saturday, December 10, 2011 5:36 PM

All replies

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

    Saturday, December 10, 2011 5:42 PM
  • 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?

    Sunday, December 11, 2011 6:43 AM
  • 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.

    Sunday, December 11, 2011 12:29 PM
  • 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.

    Sunday, December 11, 2011 2:37 PM
  • 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 :)

    Sunday, December 11, 2011 2:43 PM
  • 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:

    http://msdn.microsoft.com/en-us/library/aa918417.aspx

    That is about all I can suggest.

    Sunday, December 11, 2011 2:50 PM
  • 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).

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

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

    Sunday, December 18, 2011 4:43 PM
  • 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?

    Sunday, December 18, 2011 4:58 PM
  • 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);
        Helpers.RiaExtendTimeOutUtility.ChangeRiaSendTimeout(this, twentyMinutes);
    }

    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.

    Monday, December 19, 2011 5:29 PM
  • You can certainly put the values in code.  However, if you need to lengthen the timeouts, you will have to recompile and redistribute your app.  The client config can be edited on the server without changing the app.

    Tuesday, December 20, 2011 9:56 AM
  • 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.

    Friday, December 23, 2011 2:02 PM
  • 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. 

    Sunday, December 25, 2011 10:20 AM
  • 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?

    Tuesday, December 27, 2011 9:58 AM
  • You didn't say whether you were using the binaryMessageEncoding.

    However, I'm afraid at this point, I'm out of ideas.

    Tuesday, December 27, 2011 10:32 AM
  • 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.

    Monday, January 02, 2012 4:46 PM
  • I would be pleasantly surprised of SL 5 made any difference.

    Monday, January 02, 2012 8:24 PM