I have a WCF app that I'm trying to get to timeout after a small timeout interval. I've adjusted the timeouts to about 2 seconds, but the code will hang for about 22 seconds when I attempt to call Open() on the proxy object. I get an EndpointNotFoundException with message "Could not connect to net.tcp://10.22.104.64:6789/MyContract. The connection attempt lasted for a time span of 00:00:01.9062500. TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
Obviously the code thinks it's timing out in 2 seconds, but in reality the Open call blocks for far longer. A client that's running responds perfectly within this interval of time. Any ideas?
// Example code that calls the proxy
MyProxy.GetProxy(IPAddress.Parse("10.22.104.64"), 6789, validator).Open()
// Exception caught here indicates the timeout occurred after just under 2 seconds, but in reality it was about 22
// Example code that creates the proxy
public class MyProxy : ClientBase<IMyContract>, IMyContract
public static MyProxy GetProxy(IPAddress ipAddress, int port, X509CertificateValidator validator)
// Create a TCP binding
// Require transport security, encryption/signatures, and a client certificate
NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.Transport);
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
tcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
TimeSpan ts = TimeSpan.FromSeconds(2);
tcpBinding.CloseTimeout = ts;
tcpBinding.OpenTimeout = ts;
tcpBinding.ReceiveTimeout = ts;
tcpBinding.SendTimeout = ts;
// Create a TCP address
Uri tcpAddress = new Uri("net.tcp://" + ipAddress.ToString() + ":" + port.ToString() + "/MyContract");
// Create a DNS identity based on what the remote host's certificate will claim
DnsEndpointIdentity tcpIdentity = new DnsEndpointIdentity("MyClientName");
// Create the TCP endpoint
EndpointAddress tcpEndpoint = new EndpointAddress(tcpAddress, tcpIdentity);
// Create the proxy
MyProxy proxy = new MyProxy(tcpBinding, tcpEndpoint);
// Enable custom validation of the server's certificate
proxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
proxy.ClientCredentials.ServiceCertificate.Authentication.CustomCertificateValidator = validator;
I wonder how long it takes to return the proxy after your call to GetProxy. Not that this would take 20 seconds, but it can help to isolate the problem. My guess is that there is a lot of stuff going on during Open that don't count towards the Open timeout. Things like setting up the secure channel, the transaction layer, etc. That's just a guess, though.
I would have thought that too, except that if the target machine is up and running, the code will open the channel, perform a requested operation, and close the channel in under 2 seconds.
As a workaround, I've found that by using the asynchronous open, I can ensure I only wait 2 seconds before giving up, but I'd really prefer to just be able to call my method on the Channel object and not worry about it not enforcing my timeouts. Also, I think it's funny that the error returned shows that the underlying class that's being used for TCP gives up after 2 seconds, but it takes well over 20 for the entire operation to abort.
This is a long shot, but are you using InfoCard or something that uses an IInteractiveChannelInitializer? That portion of the 'Open' call doesn't run under the timeout (since it is designed to pop up UI and wait for human interaction). But I doubt this is the issue here (if it were, you probably wouldn't be asking the question).
Can you break in the debugger during this 'wait' and capture a call stack?
I encounter the same problem as described above. Depending on the address used, it takes about 21 to 22 seconds before anything happens with the first call to the service. With anything I mean a normal response from the service, an exception, etc. It does not matter whether you use certificates or any other custom security. Also, svcutil.exe and Internet Explorer block as well for abound 22 seconds when you try to access your service.
I found out that if you make another call to the service, the call returns immediatly as expected. Therefore, the delay seems to be during the connection process of the WCF service.
Changing the base address is one of the only ways to influent the internal connection process as far as I know. So I tried this. I changed the base address from http://d620jhs/... (d620jhs is my computer name) to http://localhost/.... This made everything work perfectly (no delays that is). To me, this behavior is quite strange and unexpected.
For your information, my computer is not part of a domain and has a DNS suffix. The latter might be part of the problem: when I add a line to the HOSTS file where I map my computer name (d620jhs) to 127.0.0.1, the delay disappears as well. Therefore, it seems to me that it takes WCF about 22 seconds to search the network and find the right computer. I do not experience any similar problems with other software.
I hope this helps. Best regards,
I've got the same problem and I've found a way to solve it.
The 22 second timeout is due to the connection timeout of the sockets WCF uses. Unfortunately, this connection timeout isn't configurable but is fixed by the operating system.
This forum thread
gave me the right idea:Code Snippet
DimoAsyncResult As IAsyncResult Dim fOpenCompleted As Boolean
oAsyncResult = proxy.BeginOpen(Nothing, Nothing)
fOpenCompleted = oAsyncResult.AsyncWaitHandle.WaitOne(connectionTimeoutInMilliseconds,True)
If fOpenCompleted Then'All right proxy open
proxy.EndOpen(oAsyncResult)Else 'Timeout elapsed!
proxy.Close()Throw New ApplicationException
The trick is using BeginOpen and the WaitHandle returned in the IAsyncResult to wait a specified "connection timeout" for the opening of the proxy. If we return from the WaitOne because BeginOpen terminated, then we call EndOpen and we can use the proxy; otherwise, we close the proxy and throw an exception (or do something else).
Note that the BeginOpen overload with the timeout parameter doesn't work - we have to use the wait handle.
Hope this helps.