How to Tell When Httpclient Has Timed Out

httpClient call in C# goes to timeout, while cUrl is working

Thanks everyone who commented, especially to @jdweng . It gave me some idea where to search for the problem.
So, the timeout problem was caused by TLS authentication. The root certificates were not imported on server. After importing root certificates, the problem was solved.

The bad thing is that it was impossible to figure out the exact problem from an exception text.

HttpClient getting timed out even after setting Timeout.Infinite

I have tried following code for Android and iOS and it seems working and can wait little longer on socket while fetching data using webservice

in Xamarin.Android following code is used and exposed it using DependencyService

 public HttpClientHandler GetHttpClientHandler()
{

Xamarin.Android.Net.AndroidClientHandler http = new Xamarin.Android.Net.AndroidClientHandler();
http.ReadTimeout = TimeSpan.FromMinutes(5.0);

return http;
}

in Xamarin.iOS following code is used and exposed it using DependencyService

HttpMessageHandler IHttpHandler.GetHttpHandler()
{

NSUrlSessionConfiguration sessionConfig = NSUrlSessionConfiguration.DefaultSessionConfiguration;
sessionConfig.TimeoutIntervalForRequest = 300;
sessionConfig.TimeoutIntervalForResource = 300;
sessionConfig.WaitsForConnectivity = true;

NSUrlSessionHandler sessionHandler = new NSUrlSessionHandler(sessionConfig);

return (sessionHandler);
}

Note : in case of iOS it will return HttpMessageHandler

Usage in Xamarin.Forms

   HttpClient client = new HttpClient(DependencyService.Get<IHttpClientHandler>().GetHttpClient());

However, there is one catch over here , in case of iOS if app is fetching the data using HttpClient and if user locks the screen by pressing the lock button in iPhone then the service gets immediately interrupted and throws Connection Interrupted and socket gets closed. if anyone could find any solution to this then feel free to post

HttpClient with infinite time out throws time out exception

Although the default value for Stream.CanTimeout is false, returning a stream via the response.Content.ReadAsStreamAsync() gives a stream where the CanTimeout property returns true.

The default read and write time out for this stream is 5 minutes. That is after five minutes of inactivity, the stream will throw an exception. Much similar to the exception shown in the question.

To change this behavior, ReadTimeout and/or the WriteTimeout property of the stream can be adjusted.

Below is the modified version of the ListenForSearchQueries method that changes the ReadTimeout to Infinite.

public static async void ListenForSearchQueries(int resourceId)
{
var url = $"xxx/yyy/{resourceId}/waitForSearchRequest?token=abc";

var httpHandler = new HttpClientHandler { PreAuthenticate = true };

using (var digestAuthMessageHandler = new DigestAuthMessageHandler(httpHandler, "user", "password"))
using (var client = new HttpClient(digestAuthMessageHandler))
{
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);

var request = new HttpRequestMessage(HttpMethod.Get, url);

var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromMilliseconds(Timeout.Infinite));

using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, tokenSource.Token))
{
Console.WriteLine("\nResponse code: " + response.StatusCode);

using (var body = await response.Content.ReadAsStreamAsync())
{
body.ReadTimeout = Timeout.Infinite;

using (var reader = new StreamReader(body))
while (!reader.EndOfStream)
Console.WriteLine(reader.ReadLine());
}
}
}
}

This fixed the exception which was actually being thrown by the stream but seemed like was being thrown by the HttpClient.

HttpClient - how to figure out if server is down faster?

You can't handle this with timeouts, as mentioned in msdn:

A Domain Name System (DNS) query may take up to 15 seconds to return or time out. If your request contains a host name that requires resolution and you set Timeout to a value less than 15 seconds, it may take 15 seconds or more before a WebException is thrown to indicate a timeout on your request.

However, another approach would be wrapping your request in another task and handle timeout from there:

var task = Task.Run(() => { 
var req = new HttpClient().GetAsync("http://www.google.com");
if (!req.Wait(10000))//wait for 10 seconds
throw new TaskCanceledException(req);
});
task.Wait();


Related Topics



Leave a reply



Submit