11

I've been reading a lot of WCF articles online and it seems like most people cache the ChannelFactory objects but not the channels itself. It appears that most people are afraid to use channel caching because they don't want to handle the network faults that could render the cached channel unusable. But that could be easily fixed by catching the CommunicationException on the method, recreate the channel, and replay the method using Reflection.

Then there are people who think it's bad to do channel caching because all communication will go through a single channel. See following article.

http://social.msdn.microsoft.com/Forums/is/wcf/thread/9cbdf92a-a749-40ce-9ebe-3f2622cd78ee

Is this necessarily a bad thing? Can you not share channels across threads? Will performance suffer because multiple method calls made to this single channel will get processed serially?

I haven't found evidence that sharing channels will degrade performance. What I did find is that using a cached channel is about 5 times faster than using a non-cached channel, even if it means having to use Reflection to make the methods calls on the cached channels.

The other advantage is not having to surround all your WCF calls with try/catch/finally statements to call Close(), Abort(), or Dispose() on the channel when you are done with it. To me it seems like WCF took a step in the wrong direction by forcing developers to have to manage WCF channel resources. In .NET Remoting, you created the proxy using the Activator class and you didn't have to do anything to it to clean it up. The .NET Framework handled all of that for you.

Bart
  • 167
  • 1
  • 6

1 Answers1

10

2 main reasons:

  1. A ChannelFactory is expensive to create and it is thread safe => perfect candidate for caching.
  2. A Channel generated by a channel factory is not expensive to create but it is not thread safe (well in reality it is thread safe but concurrent calls will be blocked and executed sequentially) => don't cache it in a multithreaded environment.

Here's a nice article which goes into further details.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • @Tom C. here's a [nice article](http://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx) which goes into further details. According to it the channels are indeed thread safe but will block concurrent access and execute them sequentially. – Darin Dimitrov Jun 02 '11 at 21:16
  • Depending on WCF options being used Channels can contain state specific to a certain session. So best advice is definitely: cache the factory, not the channel. – Drew Marsh Jun 02 '11 at 22:06
  • Yes, I agree that concurrent calls on the same channel will be executed sequentially and may be a problem in a multithreaded environment. But that can be solved with channel pooling. Creating a channel may not be as expensive as creating the ChannelFactory but there is still a cost to it. And this cost adds up over time and be unacceptable for some high performance systems. – Bart Jun 03 '11 at 14:28
  • 2
    Perhaps Microsoft thinks that most software systems can live without the performance gain of caching channels but this still doesn't explain why Microsoft is forcing the developer to control the channel cleanup. Why make the developer have to cast their to proxy to an IClientChannel so that the developer can determine whether or not to call Close()/Abort()/Dispose() on the channel. Why can't this be done automatically as part of Garbage Collection as the channel goes out of scope. – Bart Jun 03 '11 at 14:37