.Net HttpClient.timeout means what? - c#

I am working on HttpClient.timeout in .NET Core 2.2. I am wondering that - the timeout here counts the connection time (time when the request builds the connection with the remote host) and the socket time (after connection builds, the time for the host to wait for incoming data) as a whole or just connection time?
I've searched the official docs here but there seems no explanation. Could anyone help me? Thank you.

with WinHttpHandler You can set different timeouts as you can see bellow
var httpMessageHandler = new System.Net.Http.WinHttpHandler();
httpMessageHandler.SendTimeout = TimeSpan.FromSeconds(150);
httpMessageHandler.ReceiveDataTimeout = TimeSpan.FromSeconds(80);
httpMessageHandler.ReceiveHeadersTimeout = TimeSpan.FromSeconds(70);
var httpClient = new HttpClient(httpMessageHandler);
httpClient.Timeout = TimeSpan.FromSeconds(200);
for you question as far as i know httpClient.Timeout is the whole but you can test it with the above.

Related

In .NET, failure to retrieve HTTP resource from W3C web site

Retrieving the resource at http://www.w3.org/TR/xmlschema11-1/XMLSchema.xsd takes around 10 seconds using the following mechanisms:
web browser
curl
Java URL.openConnection()
It's possible that the W3C site is applying some "throttling" - deliberately slowing the response to discourage bulk requests.
Trying to retrieve the same resource from a C# application on .NET, I get a timeout after about 60-70 seconds. I've tried a couple of different approaches, both with the same result:
System.Xml.XmlUrlResolver.GetEntity()
new WebClient().OpenRead(uri)
Anyone have any idea what's going on? Would another API, or some configuration options, solve the problem?
The problem is they are (probably) checking for a User-Agent string. If it's not present, they send you to purgatory. .NET's http clients do not set this by default.
So, give this a shot:
private static readonly HttpClient _client = new HttpClient();
public static async Task TestMe()
{
using (var req = new HttpRequestMessage(HttpMethod.Get,
"http://www.w3.org/TR/xmlschema11-1/XMLSchema.xsd"))
{
req.Headers.Add("user-agent",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)");
using (var resp = await _client.SendAsync(req))
{
resp.EnsureSuccessStatusCode();
var data = await resp.Content.ReadAsStringAsync();
}
}
}
No idea why they do this; Maybe it's a bug in their back-end? (I sure wouldn't want to leave a socket open longer than it needs to be for no good reason). The request still takes 10-15 seconds, but it's better than the 120+ second timeout.

Cloudant endpoint DNS cannot be resolved

We have for some time been using Cloudant NoSQL from the IBM Cloud and we have been extremely happy with the speed, simplicity and reliability. BUT a few weeks ago our front-end server which stores data in Cloudant database startet periodically to log exceptions: "The remote name could not be resolved: '[A unique ID]-bluemix.cloudant.com" at System.Net.HttpWebRequest.EndGetRequestStream.
I added a DNS lookup when the error occurs which logs: "This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server" at System.Net.Dns.GetAddrInfo(String name).
This relaxed error message indicates it is not harmful but for us it is.
We see the error for 1-3 minutes every 30-120 minutes on servers but not while debugging locally (this could be lack of patience and/or traffic).
Below is one method of seven which fails
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.Credentials = new NetworkCredential(Configuration.Cloudant.ApiKey, Configuration.Cloudant.ApiPassword);
using (var client = new HttpClient(handler))
{
var uri = new Uri(Configuration.Cloudant.Url); //{https://[A unique ID]-bluemix.cloudant.com/[Our Product]/_find}
var stringContent = new StringContent(QueryFromResource(),
UnicodeEncoding.UTF8,
"application/json");
var task = TaskEx.Run(async () => await client.PostAsync(uri, stringContent));
task.Wait(); // <------ Exception here
if (task.Result.StatusCode == HttpStatusCode.OK)
{
// Handle response deleted
}
}
}
We have updated our .Net framework, experimented with DnsRefreshTimeout, refactored code, extended caching but we keep seeing the issue.
We also added a DNS lookup to Google when the error occurs and this is consistently successful.
Initially we thought load might we an issue but we see the issue even when there is no traffic.
Suggestions are much appreciated!

How do you make gRPC client Timeout in C# if the server is down?

I am writing a connection back to a TensorFlow Serving system with gRPC from a C# platform on MS Windows 10. I have seen many references to Time-out and Dead-line with the C++ API for gRPC, but can't seem to figure out how to for a timeout under C#.
I am simply opening a channel to the server, setting up a client and the calling to the server. I would like this Classify to time-out after 5 seconds or so. Any help or direction would be appreciated.
channel = new Channel(modelServer, ChannelCredentials.Insecure);
var client = MyService.NewClient(channel);
MyResponse classvalue = client.Classify(featureSet);
To set the deadline for a call, you can simply use the following "deadline:"
client.Classify(featureSet, deadline: DateTime.UtcNow.AddSeconds(5));
or
client.Classify(featureSet, new CallOptions(deadline: DateTime.UtcNow.AddSeconds(5)));
Both ways should be easily discoverable by code completion.
GRPC timeout to detect server down scenario needs to be used on the call to connect the channel. I did it like this:
private async void SampleCode()
{
var client = await GetClient();
var data = await client.GetAllTemplatesAsync(request, new
CallOptions().WithDeadline(DateTime.UtcNow.AddSeconds(7)));
}
private async Task<MyGrpcClient> GetClient()
{
var channel = new Channel("somehost",23456, ChannelCredentials.Insecure);
await channel.ConnectAsync(deadline: DateTime.UtcNow.AddSeconds(2));
return new MyGrpcClient(channel);
}
So, if the server is down the call to GetClient() will timeout. Where as if the server is up but response takes too long then the timeout on the client service call will take effect.

Why would my C# app fail on this REST request but but works fine through a browser?

I have a C# app and I am accessing some data over REST so I pass in a URL to get a JSON payload back. I access a few different URLs programmatically and they all work fine using this code below except one call.
Here is my code:
var url = "http://theRESTURL.com/rest/API/myRequest";
var results = GetHTTPClient().GetStringAsync(url).Result;
var restResponse = new RestSharp.RestResponse();
restResponse.Content = results;
var _deserializer = new JsonDeserializer();
where GetHTTPClient() is using this code below:
private HttpClient GetHTTPClient()
{
var httpClient = new HttpClient(new HttpClientHandler()
{
Credentials = new System.Net.NetworkCredential("usr", "pwd"),
UseDefaultCredentials = false,
UseProxy = true,
Proxy = new WebProxy(new Uri("http://myproxy.com:8080")),
AllowAutoRedirect = false
});
httpClient.Timeout = new TimeSpan(0,0, 3500);
return httpClient;
}
so as i said, the above code works fine but a bunch of different request but for one particular request, I am getting an exception inside of the
.GetStringAsync(url).Result
call with the error:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host
I get that error after waiting for about 10 minutes. What is interesting is that if I put that same URL that isn't working into Internet Explorer directly I do get the JSON payload back (after about 10 minutes as well). So i am confused at why
It would work fine directly from the browser but fail when using the code above.
It fails on this one request but other requests using the same code work fine programmatically.
Any suggestions for things to try or things I should ask the owner of the server to check out on their end to help diagnose what is going on?
I think the timeout is not an issue here, as the error states that connection has been closed remotely and the set timeout is about 58 minutes, which is more than enough compared to your other figures.
Have you tried looking at the requests itself? Might want to edit your question with those results.
If you remove line httpClient.Timeout = new TimeSpan(0,0, 3500); the issue should be solved but if the request would last 20 minutes you should wait all the time.

Why is the WCF Client timeout ignored

I have a WCF client with the following piece of code written:
MyClient myClient = new MyClient();
string id = Guid.NewGuid();
string result = myClient.Foo(id);
Console.WriteLine(result);
This works, but I want to add a time limit for the service call, so an exception will be thrown if the operation takes too long. I tried adding the timeout in the config file at the binding element like so:
<basicHttpBinding>
<binding
receiveTimeout="00:00:05"
sendTimeout="00:00:05"
</binding>
</basicHttpBinding>
This doesn't seem to work sadly.
I also tried setting it manually in the code file like so:
MyClient myClient = new MyClient();
myClient.Endpoint.Binding = new BasicHttpBinding()
{
SendTimeout = new TimeSpan(0, 0, 5),
ReceiveTimeout = new TimeSpan(0, 0, 5)
};
string id = Guid.NewGuid();
string result = myClient.Foo(id);
Console.WriteLine(result);
But again, it doesn't seem to work.
I tested it with a really slow service, and after 20 minutes it finally returned with the (correct) answer, but a timeout exception was not thrown.
Is it possible that the WCF service I am trying to reach is somehow blocking timeouts?
I've been down this rabbit hole before. I think OperationTimeout might be what you're looking for.
(myClient as IClientChannel).OperationTimeout = TimeSpan.FromSeconds(5);
Answering my own question, almost a year later.
I originally left this bug unresolved since it used to rarely happen. It resurfaced recently so I had to dig into it once again.
As I found out, a TimeoutException wasn't thrown, simply because the SOAP request finished successfully. A timeout is only honoured from the moment the request goes out until a response returns. I verified that using fiddler. But still my code was hanging for hours.
It appears the part blocking my code was simply the parsing of the SOAP response. The default WCF parser was simply hanging forever when trying to parse specific responses as XElement.
I'm playing around with using different custom parsers and will post the results when I finish.

Categories