Monday, July 14, 2008

WCF Insights, OR: Playing Hide and Seek with it

I'm writing this post about 5 minutes after I succeeded solving my 3-days-going-round-in-circles code problem.
Yeah... it's those days you want to forget and repress. You feel lost, you feel confused, you've tried every code change, every trick. You drank tons of coffee and went back and forth. You Googled and Yahooed and Altavistad everywhere. Nada. As the old saying: "A prophet is not without honor save in his own country".

Finally (sooner or later), you're solving the problem and you immediately think about three things:

  1. "I'm so so smart that I managed to solve this problem!"
  2. "Damn! it was so easy and so around the corner that it make me sick!"
  3. "I'm gonna kill who created this API / framework / service. Bring his head to me now!"
Well, I thought about those three things right after the miracle has happend and the code suddenly worked. Now, after calming down, let me share with you some of the insights I exposed to during the problem I had using the WCF .NET component.


Problem with passing large and complex objects using WCF

This is a common one with many reference in the serach sites. You may want to pass large DataTables or complex object with many nested lists you created. If you encountered an exception in the client side it might be caused by several reasons. Check this list to see if you configured everything correctly:

  1. Too short timeout confiugration
  2. Too small received massage size
  3. Too small buffer size
  4. Too small buffer pool size
  5. Too small value for the "maxItemsInObjectGraph"

Here is the WCF configuration schema as a reference. You should be aware that giving too high values in the configuration section, may lead to DoS (Denial of Service attack). So if you care for your server, give it reasonable values according to real size estimations you have. If you don't have a clue about size estimations, tune it by starting with relatively small values and continue increasing it until everything runs ok.

If the communication is duplex (i.e., the server and client both send and receives data), you should set this configuration in both sides.


WCF service started it's job, but the client crashes or stuck

  1. Unsupported types: Make sure that all data members in your data contract objects are serializable and has no known problems in the serialization period. Specifically in my code, there was a problem using DateTime type. Several websites support this phenomenon (such as this one) and suggests to use the OffsetDateTime instead. The OffsetDateTime type has also the advantage of controlling time zones, which is a very important issue in distributed, service-based, systems. Here is the MSDN reference for it.
  2. Unhandled server-side exceptions: You should know that that the server may encounter with exceptions it may suppress, and thus - not letting the service operation to be completed. Thus, the client is unaware of the reason why nothing happens or crashes. Handling this situation requires the usage of the "FaultContractAttribute". See more details about it, and how to use this attribute, here.
  3. Use a suitable binding method for your purposes: There is a big difference in the funcionality among the built-in binding types that WCF supply. Queued, HTML based, TCP based, secured or not, reliable or not, duplex communication or not. This article will help you decide. Make sure to configure the client endpoint and the service sections with matching definitions (for example, don't mess wsHttpBinding with netTcpBinding).


WCF service methods are not responding during asynchronous calls

If you're using asynchronous calls with the WCF service, and it "just doesn't work", it might be caused by other problems which are not part of the asynchronous game. If you isolated the problem and sure it is an async problem, check out that:

  1. Your proxy class code is synchronized with the one in the server. Sometimes you just forget to recreate the proxy class after performing changes in the server code.
  2. You didn't miss the "IsAsync=true" attibute of the OperationContract in the relevant method.
  3. You're using safe operations (using locks) when multithreaded operations are involved.
  4. You're waiting for the async operation to complete (like using "WaitOne" method in the IAsynchResult model), and the calling thread not "running away".

You should know that WCF has two main attitudes to manage asynchronous calls. Make sure you follow it's rules:

  1. The tranditional way. Event based or IAsynchResult model. Take a look in Dan Rigsby's wonderful series of posts, here.
  2. Using WCF callback interface. CallbackContract attribute is used here to determine who is the interface which is managed to perform the callback operations. Take a look in idunno.org website, here.

That's it for now. If you have more insights and tips to share, a reply would be grateful for everyone.

Have a nice WCF experiments!