views:

189

answers:

3

I have a web tier that forwards calls onto an application tier. The web tier uses a shared, cached channel to do so. The application tier services in question are stateless and have concurrency enabled.

But they are not being called concurrently.

If I alter the web tier to create a new channel on every call, then I do get concurrent calls onto the application tier. But I want to avoid that cost since it is functionally unnecessary for my scenario. I have no session state, and nor do I need to re-authenticate the caller each time. I understand that the creation of the channel factory is far more expensive than than the creation of the channels, but it is still a cost I'd like to avoid if possible.

I found this article on MSDN that states:

While channels and clients created by the channels are thread-safe, they might not support writing more than one message to the wire concurrently. If you are sending large messages, particularly if streaming, the send operation might block waiting for another send to complete.

Firstly, I'm not sending large messages (just a lot of small ones since I'm doing load testing) but am still seeing the blocking behavior. Secondly, this is rather open-ended and unhelpful documentation. It says they "might not" support writing more than one message but doesn't explain the scenarios under which they would support concurrent messages.

Can anyone shed some light on this?

Addendum: I am also considering creating a pool of channels that the web server uses to fulfill requests. But again, I see no reason why my existing approach should block and I'd rather avoid the complexity if possible.

+1  A: 

You can cache the WCF proxy, but still create a channel for each service call - this will ensure concurrency, is not very expensive in comparison to creating a channel from scratch, and re-authentication for each call will not be necessary. This is explained on Wenlong Dong's blog - "Performance Improvement for WCF Client Proxy Creation in .NET 3.5 and Best Practices" (a much better source of WCF information and guidance than MSDN).

Bermo
+1 As per the addendum in my question, pooling is my backup approach. However, I'd still like to know the circumstances under which a single proxy can be successfully shared with concurrency. Unless I missed something, that blog post does not cover those circumstances.
Kent Boogaart
A: 

After much ado, this all came down to the fact that I wasn't calling Open explicitly on the channel before using it. Apparently an implicit Open can preclude concurrency in some scenarios.

Kent

Kent Boogaart
great. could you please add a reference?
Yonatan Karni
To be honest, I don't think I have one. There are various posts such as http://blogs.msdn.com/b/mjm/archive/2006/11/13/auto-open-part-1.aspx that provided hints for me, but I haven't seen one that explicitly showed how auto-open precludes concurrent calls. I remember intending to do my own post at the time, but never got around to it. I'll add it to my queue and post back here when it's up.
Kent Boogaart
A: 

Just for completeness: Here is a blog entry explaining the observed behavior of request serialization when not opening the channel explicitly:

http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

Jan