views:

510

answers:

4

All,

I have a WCF service that times out intermittently, usually after about ten or twelve requests from the asp.net client. The service uses reflection to find classes in its assembly (WAP dll) that have a custom attribute set. The process itself is very quick, usually taking only a few milliseconds, and when it works, it works great.

Setting a breakpoint in the calling code and in the service itself tells me that the timeout is occurring between the call from the WCF client proxy class and when that method is actually executed.

Ideas?

Update: binding, etc from web.config:

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Sdd.Services.ControlPanelBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="Sdd.Services.ControlPanelBehavior"
        name="Sdd.Services.ControlPanel">
        <endpoint address="" binding="wsHttpBinding" contract="Sdd.Services.IControlPanel">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

UPDATE: And here's the relevant portion from the client's web.config:

 <system.serviceModel>
  <bindings>
   <wsHttpBinding>
    <binding name="WSHttpBinding_IControlPanel" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
     textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <reliableSession ordered="true" inactivityTimeout="00:10:00"
      enabled="false" />
     <security mode="Message">
      <transport clientCredentialType="Windows" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="Windows" negotiateServiceCredential="true"
       algorithmSuite="Default" establishSecurityContext="true" />
     </security>
    </binding>
   </wsHttpBinding>
  </bindings>
  <client>
   <endpoint address="http://localhost:81/services/ControlPanel.svc"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IControlPanel"
    contract="PublicSite.IControlPanel" name="WSHttpBinding_IControlPanel">
    <identity>
     <dns value="localhost" />
    </identity>
   </endpoint>
  </client>
 </system.serviceModel>
+2  A: 

A good way to help diagnose this type of problem is to enable tracing on the client and the server and using the Service Trace View Tool. That will give you a better idea of exactly where (in what method or call) the problem is.

JP Alioto
A: 

Unfortunately, the most important pieces of the config (the bindings and service endpoints) is missing - and so is the client config.

But the way you describe it, that 10-12 requests seem to work fine and then there's a failure, could point to an issue with concurrency/throttling on the server.

I would try to increase the number of concurrent calls and sessions just to see if that helps anything. To do so, you'll need to add a serviceThrottling section to your behavior config on the server:

<behavior name="Sdd.Services.ControlPanelBehavior">
   <serviceMetadata httpGetEnabled="true" />
   <serviceDebug includeExceptionDetailInFaults="false" />
   <serviceThrottling
      maxConcurrentCalls="25"          // default is 16
      maxConcurrentSessions="25"       // default is 10
      maxConcurrentInstances="25" />   // no default
</behavior>

If that helps - you had an issue with too many sessions or concurrent calls being opened. wsHttpBinding protocol by default will use a session, so maybe you'll just need to tell it to use per-call instead.

Marc

marc_s
A: 

Whoops!

This is probably the most idiotic of mistakes, but I figured out the problem: since I'm used to using web references (.asmx web service) instead of service references (WCF), I neglected to close the proxy object. Changed

 [WebMethod]
    public static List<Page>PagesGetAll()
    {
        ControlPanelClient cp = new ControlPanelClient();
        Page[] pageArray = cp.NavigationPagesGetAll();
        List<Page> pageList = pageArray.ToList<Page>();

        // make sure that the page list in the database is up-to-date.
        foreach(Page page in pageList)
            Navigation.PageUpdate(page);

        return pageList;
    }

to

    public static List<Page>PagesGetAll()
    {
        List<Page> pageList = null;

        using (ControlPanelClient cp = new ControlPanelClient())
        {
            Page[] pageArray = cp.NavigationPagesGetAll();
            pageList = pageArray.ToList<Page>();
            // implied cp.Close() from "using" statement
        }

        // make sure that the page list in the database is up-to-date.
        foreach(Page page in pageList)
            Navigation.PageUpdate(page);

        return pageList;
    }

And the problem disappeared. After verifying this solution I also increased the number of concurrent requests as it seems logical that having more than 10-12 concurrent requests would create the same problem I was seeing before.

Thanks everyone!

David Lively
Lol, I added a comment to the question above about Abort/Close of the proxy before I saw the answer (wrong sort order of answers) :D
Johan Danforth
+1  A: 

Great post guys. Not closing the service was my issue as well.

Thanks!

mrbaseball2usa