Note that there are some explanatory texts on larger screens.

plurals
  1. POWCF Concurrent requests piling up on the server when using WSHttpBinding
    primarykey
    data
    text
    <p>I have a WCF client/server app which is communicating over HTTP using the WSHttpBinding.</p> <p><strong>Server Setup</strong>: self-hosting, using the standard WCF <code>ServiceHost</code>. My actual service class is attributed as:</p> <pre><code>[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerSession, UseSynchronizationContext = false)] </code></pre> <p><strong>Client Setup</strong>: using a visual-studio generated client proxy using <em>synchronous</em> service calls (<code>proxy.call_server_method</code> blocks until such time as the server has responded in full.)</p> <p><strong>Scenario</strong>: I have one particular method call which takes 20 seconds to execute on the server. The client calls this method in a separate thread, so it is not being held up, and the <code>ConcurrencyMode.Multiple</code> means WCF should execute it in a separate thread on the server as well.</p> <p>This theory is supported by the fact that when I configure my app to use <code>NetTcpBinding</code>, everything works fine.</p> <p><strong>Problem</strong>:<br> If I configure the app to use <code>WSHttpBinding</code>, then this long method call causes the http requests to 'back up'. I have verified this behaviour both from inspecting my logs, and by debugging the HTTP requests using fiddler.</p> <p>Example:</p> <ul> <li>Client initiates 20-second long request on a background thread</li> <li>Client initiates request B and C on foreground thread</li> <li>Requests B and C get sent to the server, which doesn't process them until it is done with the 20-second long request</li> </ul> <p>But sometimes:</p> <ul> <li>Requests B and C <em>do not get sent</em> (they don't even appear in fiddler) until the 20-second request comes back (this is rare). <ul> <li>Note: setting <code>&lt;add address="*" maxconnection="100"/&gt;</code> in the client's app.config made this (appear to) stop happening.</li> </ul></li> <li>Request B gets sent and receives a response immediately, while request C is held back until the 20-second one completes (this is rare)</li> </ul> <p>Here's a timeline from fiddler demonstrating the problem: (click for bigger version)</p> <p><a href="http://farm4.static.flickr.com/3311/3510636841_2a27435eec_o.png" rel="nofollow noreferrer"><img src="https://farm4.static.flickr.com/3311/3510636841_18f9b2b0a1.jpg" /></a></p> <p>As you can see, the requests are all getting backed up at the server. Once the 20-second request completes, the responses all come flooding through, but note that there are some requests which <em>aren't</em> getting held up...</p> <p>So, <strong>Questions</strong>:</p> <ul> <li>What the heck is going on here? Why does it work fine using <code>NetTcpBinding</code> and not work using <code>WSHttpBinding</code>?</li> <li>Why the inconsistent behaviour?</li> <li>What can I do to fix it?</li> </ul> <p>Notes:</p> <ul> <li>It's not locking on the server. I've set breakpoints and used <code>!syncblk</code> and it consistently reports no locks are being held.</li> <li>It's not my threading (NetTcpBinding shouldn't work otherwise)</li> <li>I have <code>&lt;serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /&gt;</code> set in the server's app.config</li> <li>The 20-second call is just waiting on a timer, it's not thrashing the CPU or disk or network</li> <li>I'd prefer a solution that didn't involve re-architecting the application to use asynchronous calls... it's a big bunch of legacy code and I really don't want to be messing with stuff I don't understand.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload