Question
How to configure the TCP timeout for a single WebRequest?
Context
According to the docs, WebRequest.Timeout:
The length of time, in milliseconds, until the request times out, or the value Timeout.Infinite to indicate that the request does not time out. The default value is defined by the descendant class.
Requesting web resource from an non-existent endpoint (IIS without service bindings on the requested port) fails with a different and constant timeout of about 21 seconds.
According to this serverfault answer this appears to be a connect TCP timeout.
Sample Code
public static async Task<string> WebRequestToString(string requestUri, int timeoutMilliseconds)
{
var request = WebRequest.Create(requestUri) as HttpWebRequest;
request.KeepAlive = false;
request.Timeout = timeoutMilliseconds;
request.ReadWriteTimeout = timeoutMilliseconds;
using (var response = await request.GetResponseAsync() as HttpWebResponse)
{
// Get the response stream
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseBody = await reader.ReadToEndAsync();
return responseBody;
}
}
}
static void Main(string[] args)
{
string uri = "http://10.15.1.24:8081/thiservicedoesnotexist/";
int timeoutMilliseconds = 10;
Stopwatch sw = new Stopwatch();
sw.Start();
try
{
WebRequestToString(uri, timeoutMilliseconds).Wait();
}
catch (AggregateException ex)
{
Console.WriteLine(ex.ToString());
}
sw.Stop();
Console.WriteLine("Elaped {0}ms", sw.ElapsedMilliseconds);
Console.ReadKey();
}
Example Output
System.AggregateException: One or more errors occurred. ---> System.Net.WebExcep
tion: Unable to connect to the remote server ---> System.Net.Sockets.SocketExcep
tion: A connection attempt failed because the connected party did not properly r
espond after a period of time, or established connection failed because connecte
d host has failed to respond 10.15.1.24:8081
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Sock
et s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state,
IAsyncResult asyncResult, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchron
ization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TimeoutTests.Program.<WebRequestToString>d__0.MoveNext() in \\vmware-host\
shared folders\Documents\Visual Studio 2012\Projects\TimeoutTests\TimeoutTests\P
rogram.cs:line 20
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceled
Exceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationTo
ken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at TimeoutTests.Program.Main(String[] args) in \\vmware-host\shared folders\D
ocuments\Visual Studio 2012\Projects\TimeoutTests\TimeoutTests\Program.cs:line 4
0
---> (Inner Exception #0) System.Net.WebException: Unable to connect to the remo
te server ---> System.Net.Sockets.SocketException: A connection attempt failed b
ecause the connected party did not properly respond after a period of time, or e
stablished connection failed because connected host has failed to respond 10.15.
1.24:8081
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Sock
et s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state,
IAsyncResult asyncResult, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchron
ization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TimeoutTests.Program.<WebRequestToString>d__0.MoveNext() in \\vmware-host\
shared folders\Documents\Visual Studio 2012\Projects\TimeoutTests\TimeoutTests\P
rogram.cs:line 20<---
Elaped 21169ms