posts - 50, comments - 168, trackbacks - 6

My Links

News



View Marcin Celej's profile on LinkedIn

Archives

Post Categories

WCF - why do I have to Close a service proxy?

This is one of the Windows Communication Foundation mysteries. I still don't know why the code below does not (really) work:

for (int i = 0; i < 100; i++)
{
    IMyService proxy = new ChannelFactory("MyService").CreateChannel();
    proxy.DoSomething();

    // Without this line the proxy invocation fails on the 10th DoSomething() method call
    // ((IChannel)proxy).Close();
}

 

When the proxy.Close() is commented, in the code above, the WCF throws the TimeoutException on the 11th proxy invocation (the variable i == 10). So the first 10 requests works properly and the 11th one throws the exception:

A first chance exception of type 'System.TimeoutException' occurred in mscorlib.dll

Additional information: The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.

My first thought when I figured out that it is caused by lack of the Close() method call was: Why the hell I have to close the proxy?

I tried to find out why, but the only reason I see is this one: WCF session is managed by client proxy lifetime so when you close the proxy it sends such information to serever so the remote service could be released. But my service is not session-bound so I think I don't need to close it.

I tried one more thing: I added GC.Collect() instead of the proxy.Close() and everything worked fine - destroying proxy with GC closes it.

This behavior looks weirdy to me, as it can occur not on the 11th proxy invocation but during the 13, 25 or any other if the Garbage Collector is involved. This can cause mistakes and application strange behavior.

Anyway: why do we really need to close the service proxy? I am still looking for the answer - I'll post it when I find it.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Print | posted on Tuesday, May 01, 2007 2:33 PM |

Feedback

Gravatar

# re: WCF - why do I have to Close a service proxy?

What binding are you using? Almost all of the standard bindings (including net.tcp + wsHttp) are sessionful in some way or another.

You're hitting the MaxConcurrentSessions throttle on the server (which defaults to 10). Since you're not closing the proxies when you're done with them, the first 10 calls will succeed because they can establish new sessions up to the server's limit. The 11th call will block until one of the other sessions get torn down -- either by explicitly calling proxy.Close() on the client, or by implicitly calling Close() during finalization.

Anyway, the answer to why you need to close the proxy is because closing the proxy tears down all the associated channel state and frees up space on the server to process new requests.

Hope that helps
-steve
5/6/2007 6:27 PM | Steve Maine
Gravatar

# re: WCF - why do I have to Close a service proxy?

I bet if you declare your proxy in a using block you won't have to think about it.
5/22/2007 5:40 AM | Matt Youell
Gravatar

# re: WCF - why do I have to Close a service proxy?

Dude! I'm facing the exact same problem and I can't figure out WHY I has to implcitly close the Channel. It makes no sense...

And I don't know, Steve's answer doen't convince me :s
9/11/2007 6:30 AM | Seba Gomez
Gravatar

# re: WCF - why do I have to Close a service proxy?

I got communication exception errors (only visible at service log though) when calling WCF function without closing its proxy afterward. You may see this problem I posted at :
http://forums.microsoft.com/msdn/ShowPost.aspx?postid=2127853&amp;isthread=false&amp;siteid=1&amp;authhash=37f516fa32dcced428dc90979fea5d51eb2f1434&amp;ticks=633251350662054330

However, unlike the scenario described here that the WCF function doSomething() is called repeatively in a loop, my client side program invokes a WCF function only one time in the code block. I assmue the proxy becomes out-of-scope but GC does not release it soon and the associated channel is left open.
9/11/2007 2:37 PM | Rick Lee
Gravatar

# re: WCF - why do I have to Close a service proxy?

Hey have u found solution of the same problem because i am facing the same one in my solution also and using wsHttpBindng..hoping for ur answer.
Thnx
12/25/2007 10:40 PM | kiran
Gravatar

# re: WCF - why do I have to Close a service proxy?

Hi,

I'm not sure if this is still an issue, but WCF has some default service throttling settings, which are configurable. The default setting for maxConcurrentSessions is 10 which is why you're only hitting a problem at 10 connections. To modify the defaults, add a behaviour as follows to the <system.serviceModel><behaviours> section in the config file for the service:
<behavior name="ThrottledBehavior">
<serviceThrottling
maxConcurrentCalls = "64"
maxConcurrentSessions = "50"
maxConcurrentInstances = "1"
/>
</behavior>
In the example above I have throttled concurrent sessions to 50, so I get to 50 before getting timeouts when attempting to open connections.

Once you've defined your behaviour, apply the behaviour configuration to your service by adding the "behaviourConfiguration" attribute and setting the value equals to the behaviour name defined in your behaviour configuration (in our example it would be "ThrottledBehavior").

e.g.

<service name="MyService" behaviorConfiguration="ThrottledBehavior">

If you have already applied a behaviorConfiguration attribute, just add the <serviceThrottling> section of the example above to the existing behaviour configuration.

You may also have to set MaxConnection settings on your bindings configurations.
1/15/2008 7:37 PM | Amy
Gravatar

# re: WCF - why do I have to Close a service proxy?

Thank you Amy for your hint. I already know it but thank you for your help.

Marcin
1/16/2008 10:45 AM | Marcin Celej
Gravatar

# re: WCF - why do I have to Close a service proxy?

I was having this problem too. Following Matt's comment above, I applied a using block to the service proxy object, and it solved the problem nicely.
2/16/2008 11:50 AM | Jacob
Gravatar

# re: WCF - why do I have to Close a service proxy?

http://www.cazed.com


The only proxy that seems to work...
8/10/2008 8:03 PM | Ted
Gravatar

# re: WCF - why do I have to Close a service proxy?

This post was extremely helpful. I tried both Steve's and Matt's suggestions and both worked great. I ended up going with the using statement solution.
9/3/2009 1:47 AM | Aaron
Gravatar

# re: WCF - why do I have to Close a service proxy?

Great - this list of postings have saved my day. I was having the same problem with the limit of the 10 concurrent connections and even though I did null my connection object this would not be closed before the GC would kick in much later.
I have just tried the using statement solution and it works great.
Thanks for sharing.
Peter
9/8/2009 8:49 PM | Peter
Gravatar

# re: WCF - why do I have to Close a service proxy?

Hi again,
I have just read some more about this problem and it seems that there may be a catch with the using statement.

Have a look here:
http://www.codeguru.com/csharp/.net/net_wcf/article.php/c15941/

I have tested this fix and it works in my program.

Peter
9/8/2009 9:22 PM | Peter
Gravatar

# re: WCF - why do I have to Close a service proxy?

Peter, Many thanks for the link. The tip is great. If I were you I would create a class, let's call it a ProxyDisposer that implements the IDisposable interface. The class could be used this way:

using(var client = new ProxyDisposer (new StockService.StockServiceClient(...)))
{
client.InnerProxy.GetStockIdByName("MSFT");
}

So the ProxyDisposer takes as an argument a real proxy to the service and it exposes it via InnerProxy property. In the Dispose() method the ProxyDisposer should do what is mentioned in the article you provided.

That's nice piece of utility class.

Marcin Celej
MVP Visual C#
9/8/2009 9:42 PM | Marcin Celej
Gravatar

# re: WCF - why do I have to Close a service proxy?

if u left the proxy instantiation outside the loop u wont create a new session for each call but use the same proxy for all calls,,,then you wont get the max session issue
10/5/2009 9:49 PM | ChristianLarsen
Gravatar

# re: WCF - why do I have to Close a service proxy?

See http://timrayburn.net/blog/idisposable-wcf-and-hole-in-the-middle/ for more details.
Do not use "using" construction with client proxy. It will cause the several issues!
4/1/2010 12:09 AM | BorodaAlex
Gravatar

# re: WCF - why do I have to Close a service proxy?

hi..
can some1 plzzzzz help me out this weird problem ..i tried all options given above but in vain....
9/7/2010 10:39 PM | Mumtaz
Gravatar

# re: WCF - why do I have to Close a service proxy?

Hi!

I have a WCF service with wsHttpBinding. When I add a web reference in my web application VS 2008 generates the proxy...then when I call the service proxy I can´t get the Close() method neither use "using" block because the proxy doesn't implements IDisposable. Can anybody helpe me please!!! I'm pretty new with WCF. Thank you
9/8/2010 9:23 AM | Juliana
Gravatar

# re: WCF - why do I have to Close a service proxy?

I think I might have some under-the-covers insight. I know this post is old but it is also a top search result so I had to share.

I don't know if the same reasoning applies with a named pipes binding but other bindings use TCP socket connections (since HTTP is over TCP). Socket connections will remain in a CLOSE_WAIT status until directed to close. The timeout for a CLOSE_WAIT is quite long...VERY LONG. Run NETSTAT in a command prompt to have a peak at your current connections. (Don't worry about TIME_WAIT that is like good cholesterol)

As long as that socket connection is open in a CLOSE_WAIT status , you are chewing up one of your available MaxConcurrentSessions (default 10), MaxConcurrentInstances (default 26), and MaxConcurrentCalls (default 16). Notice the defaults for those are unreasonably low for just about 99% of systems. Never accept those default values. Think about the throughput your service will accept in a full load scenario and set accordingly. At my organization, knowing my systems, I can't imagine supporting less than 100 for all three settings. If you don't close your proxies then you are maintaining 10 open sessions to your service until garbage collection gets your proxies. Yes, 10! Once you hit your service throttling thresholds, all additional requests queue up on the server. This means your 11th call is sitting in a queue waiting for the garbage collector to kill naughty clients. Since GC doesn't come to dinner often: your client timeout lapses; you recieve the error you mentioned; and Bob's your uncle.

I don't think ASMX has these throttling settings on by default (or avilable at all?) so you wouldn't likely see the clients timeout like this but you would see chaos in NETSTAT if you forgot to call Dispose on your proxy. I've had busy services chew up the entire dynamic port range because of undisposed (read: unclosed) ASMX proxy objects. It was a deluge of CLOSE_WAITS. That wasn't exacly a DoS attack however I'm thankful WCF at least lets me control when to start queuing client requests, potentially timing out clients, before my important back end resources start toppling over if there were a DoS attack.

In short:
1) Set your throttling (ALWAYS)
2) Close your proxies (Close alone doesn't cut it)
3) Close your proxies (Displose alone doesn't cut it)
4) Close your proxies (Stay away from Using blocks)
5) Close your proxies (Call Abort, not Close, if proxy is in a Faulted state)
6) Close your proxies (Don't reuse a Faulted proxy)
2/14/2011 10:41 AM | Matt Poland
Gravatar

# re: WCF - why do I have to Close a service proxy?

thx dude, my app was freezing up after... about 10 invocations :D
5/6/2011 12:55 AM | Gelu
Gravatar

# re: WCF - why do I have to Close a service proxy?

Did you find the awnser to your question?

I was wondering the same thing
10/4/2011 2:32 AM | Ryno
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: