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
Why Enums Require an Explicit Cast to Int Type
Setting Unique Constraint with Fluent API
Datetime Format to SQL Format Using C#
Create PDF in Memory Instead of Physical File
How to Best Implement Equals for Custom Types
C# Static Variables - Scope and Persistence
Serialize Property, But Do Not Deserialize Property in JSON.Net
Create a Coroutine to Fade Out Different Types of Object
Can You Configure Log4Net in Code Instead of Using a Config File
What Are Best Practices for Using Smtpclient, Sendasync and Dispose Under .Net 4.0
How to Execute Code After a Form Has Loaded
Getproperties() to Return All Properties for an Interface Inheritance Hierarchy
Asp .Net MVC Disable Client Side Validation at Per-Field Level
How to Conditionally Compile My C# for Mono VS. Microsoft .Net