I have a WCF service that sometimes has to return a Fault. For some reason, the calls to my service begins to time out with the following error: "The request channel timed out while waiting for a reply after 00:00:59.8906201. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout."
After examining the problem, a pattern emerged: When the service had returned a fault 10 times, the timeout starts. So I created a testservice implemented by:
public string GetData(int value)
{
throw new FaultException("A testerror occured");
}
And a testclient:
protected void RunTestGetData()
{
using (TestServiceReference.Service1Client client
= new WSPerformanceTester.TestServiceReference.Service1Client())
{
try
{
client.GetData(1);
client.Close();
outputWriter.WriteLine(string.Format("Call run in thread {0}: GetData()", Thread.CurrentThread.ManagedThreadId));
outputWriter.Flush();
}
catch (Exception e)
{
client.Abort();
client.Close();
outputWriter.WriteLine(string.Format("Error occured in thread {0}: GetData(): {1}", Thread.CurrentThread.ManagedThreadId, e.Message));
outputWriter.Flush();
}
}
}
This only happens, when the service is returning a FaultException. If I throw a normal exception, the service is able to continue running after the 10th call. Obviously, i would like to wrap my exceptions nicely, so just throwing normal exceptions is not a real option.
Why do I experience these timeout exceptions? Thanks in advance for any help..
I don't have enough points to comment, so new response...
Self hosted services only allow a max of 10 concurrent connections - no matter the transport. If you're running WCF services inside of IIS/WAS you shouldn't have to worry about this (unless you're on XP/Vista where the max concurrent connections is also 10).
Differences between a fault exception and a regular exception in this scenario can account for the result you're seeing.
Remember, a regular unhandled exception will fault the channel. In doing so I assume this opens up an available connection. When you return a fault, it won' automatically fault the channel because it allows you to do something with the connection and handle the fault on your end because it is a possible "expected" fault whereas an unhandled exception would not be.
Even when you return a fault, you still need to Abort() the connection. Also, underneath there are unmanaged resources so be sure to implement IDisposable on your clients/proxy's callers.