Searching the Internet for “WCF timeouts” brings up a whole lot of material. Until now, however, I have not found the place™ explaining all the different timeout settings, why they exist and what their respective side effects are. This article tries to synthesize the bits and bytes I discovered into a single, comprehensive article.
(WCF is going to evolve further – if you stumble upon this article in the future: it is written with WCF 4.5 in mind.)
There are no less than 6 timeouts in WCF and another 2 in bindings shipped with WCF:
Furthermore, most of them have a slightly different meaning on the server-side and the client-side. That is a whole lot, so let’s discuss them one at a time.
OpenTimeout & CloseTimeout
From the client’s point of view, those timeouts are pretty straightforward: WCF throws a TimeoutException if the communication channel cannot be opened/closed within the configured time span. The open/close time span includes all necessary security handshakes, protocol negotiations, etc. On the server-side the property affects connection setup and teardown for WCF callbacks.
Note: if a connection to the service endpoint cannot be established at all (i.e. the service is not reachable), WCF does not throw a TimeoutException, instead, the framework throws an EndpointNotFoundException – immediately.
The operation timeout covers the whole service call (sending the request, processing it and receiving a reply). In other words, it defines the maximum time a service call is active from a client’s point of view.
In general you do not set an operation timeout for each and every call individually. If not set, WCF initializes the operation timeout with the configured send timeout. From a different angle you could say that the operation timeout allows you to overwrite the configured send timeout if necessary.
Contrary to my first intention, this configuration setting does not only cover the time for sending the request. It is used by WCF as the default value for the operation timeout. Again, the setting affects WCF callbacks on the server-side.
Probably the most misunderstood property. It is completely ignored by WCF at the client-side (it has nothing to do with the time it takes to receive a response). The service host uses this timeout to determine when to drop idle connections. If no message is received within the configured time span the connection is closed. Of course, this presumes that the configured binding has the notion of a session (i.e., the property does not have any effect if used in combination with the BasicHttpBinding).
Whenever you use WCF reliable messaging, a second timeout must be satisfied to keep the connection alive: the inactivity timeout. Unlike the receive timeout described above, the inactivity timeout also resets if an infrastructure message is received, e.g., a keep-alive message. Under normal circumstances the underlying infrastructure makes sure to send such messages within the limits of this timeout, so it typically expires only if the network fails. As you might have already concluded, setting the inactivity timeout to a higher value than the receive timeout does not make sense.
This timeout is specific to connection-oriented transport channels (e.g., TCP or named pipes) and determines how long the channel may stay in the initializing state. Similar to the inactivity timeout, it prevents a malicious caller from opening a connection and blocking resources indefinitely. During initialization the client is not yet authenticated, which is why you might want to set an even smaller time span than the normal inactivity timeout.
This is the only timeout for which I have not found any reliable information. The default value is set to 0 seconds, which deactivates the timeout. If you know why somebody would want to configure this timeout to a different value, please visit my related StackOverflow question.
Why even have timeouts?
Setting all those configuration values to infinite might sound like a good idea to overcome timeout-related problems. As so often, security is the reason for having tight timeout constraints. It prevents malicious callers (and sloppy developers) from blocking huge amounts of resources on your server. Finding the optimal settings for your scenario requires some initial thinking and estimating, later on it should also include evaluation of service logs. Questions you should ask yourself should include: How often do clients call my service operations? How big are the requests and replies sent between the service and the client? How long does it take to process a request? In comparison to user data, how much does it cost to establish a connection? Answering these questions will result in reasonable and secure timeout configurations.
But wait, there is more…
Hey! The article is not finished yet! If your WCF service is hosted within an ASP.NET environment, there is another timeout you need to consider: The execution timeout indicates the number of seconds a request is allowed to execute before ASP.NET automatically shuts it down. Note for testing: fires only if the debug attribute in the compilation element is set to false.
Nowadays (.NET 3.0 SP1 and later) there is no more to say. The ExecutionTimeout is set to int.MaxValue for WCF requests. Thereby WCF is granted full control over its own request lifetimes.
- MSDN, Binding Class, Remarks on Timeout Properties
- MSDN, Configuring Timeout Values on a Binding
- MSDN, ReliableSession.InactivityTimeout Property
- MSDN Forums, Explaination of different timeout types
- MSDN Blog andreal, WCF netTcpBinding – What to do if…
- Various other Internet resources, personal experience & testing