Note that there are some explanatory texts on larger screens.

plurals
  1. POWCF using, closing and extensions
    primarykey
    data
    text
    <p>I am stumped. Perhaps someone can shed some light on WCF client behavior I am observing. </p> <p>Using the WCF samples, I've started playing with different approaches to WCF client/server communication. While executing 1M of test requests in parallel, I was using SysInternals TcpView to monitor open ports. Now, there are at least 4 different ways to call the client:</p> <ol> <li>Create the client, do your thing, and let GC collect it</li> <li>Create the client in a using block, than do your thing</li> <li>Create the client channel from factory in a using block, than do your thing</li> <li>Create the client or channel, but use <a href="http://omaralzabir.com/do-not-use-using-in-wcf-client/">WCF Extensions</a> to do your thing</li> </ol> <p>Now, to my knowledge, only options 2-4, explicitly call client.Close(). During their execution I see a lot of ports left in the TIME_WAIT state. I'd expect option 1 to be the worst case scenario, due to reliance on the GC. However, to my surprise, it seems to be the cleanest of them all, meaning, it leaves no lingering ports behind.</p> <p>What am I missing?</p> <p>UPDATE: Source code</p> <pre><code> private static void RunClientWorse(ConcurrentBag&lt;double&gt; cb) { var client = new CalculatorClient(); client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service"); RunClientCommon(cb, client); } private static void RunClientBetter(ConcurrentBag&lt;double&gt; cb) { using (var client = new CalculatorClient()) { client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service"); RunClientCommon(cb, client); } } private static void RunClientBest(ConcurrentBag&lt;double&gt; cb) { const string Uri = "net.tcp://localhost:8000/ServiceModelSamples/service"; var address = new EndpointAddress(Uri); //var binding = new NetTcpBinding("netTcpBinding_ICalculator"); using (var factory = new ChannelFactory&lt;ICalculator&gt;("netTcpBinding_ICalculator",address)) { ICalculator client = factory.CreateChannel(); ((IContextChannel)client).OperationTimeout = TimeSpan.FromSeconds(60); RunClientCommon(cb, client); } } private static void RunClientBestExt(ConcurrentBag&lt;double&gt; cb) { const string Uri = "net.tcp://localhost:8000/ServiceModelSamples/service"; var address = new EndpointAddress(Uri); //var binding = new NetTcpBinding("netTcpBinding_ICalculator"); new ChannelFactory&lt;ICalculator&gt;("netTcpBinding_ICalculator", address).Using( factory =&gt; { ICalculator client = factory.CreateChannel(); ((IContextChannel)client).OperationTimeout = TimeSpan.FromSeconds(60); RunClientCommon(cb, client); }); } </code></pre>
    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